﻿#region << 版 本 注 释 >>
/*----------------------------------------------------------------
// Copyright (C) 2021 kingerrobot
// 版权所有。 
//
// 文件名：BTask
// 文件功能描述：
//
// 创建者：名字 (zzl)
// 时间：2021/12/6 15:05:46
//
// 修改人：
// 时间：
// 修改说明：
// 版本：V1.0.0
//----------------------------------------------------------------*/
#endregion


using K8.MDCBB;
using K8.Redis;
using KingerRobot.MexicoSailunMDC.Dao;
using KingerRobot.MexicoSailunMDC.Spi;
using KingerRobot.MexicoSailunMDC.SpiService.DTO;


//using KingerRobot.MexicoSailunMES.Dao;
using System;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using static System.Collections.Specialized.BitVector32;

namespace KingerRobot.MexicoSailunMDC.SpiService;
public class BTask : ITask
{
    private readonly static ITaskCmd _TaskCmd = new BTaskCmd();
    private readonly static IProdProduct _ProdProduct = new BProdProduct();
    private readonly static IProdSkuProduct _ProdSkuProduct = new BProdSkuProduct();
    private readonly static IWcsEquipLoc _WcsEquipLoc = new BWcsEquipLoc();
    private readonly static IWcsNetAbnormal _WcsNetAbnormal = new BWcsNetAbnormal();
    private readonly static IWcsLocSku _WcsLocSku = new BWcsLocSku();
    private readonly static IRcsLocation _RcsLocation = new BRcsLocation();
    private readonly static IWcsAsrsCrnInput _WcsAsrsCrnInput = new BWcsAsrsCrnInput();
    private readonly static IMesCuringRequestMaterial _MesCuringRequestMaterial = new BMesCuringRequestMaterial();
    private readonly static IWcsEquipWarehouseDistance _WcsEquipWarehouseDistance = new BWcsEquipWarehouseDistance();
    private readonly static IWmsOutOrderSummary _WmsOutOrderSummary = new BWmsOutOrderSummary();
    private readonly static IRcsEquipCrn _RcsEquipCrn = new BRcsEquipCrn();
    private readonly static IProdSku _ProdSku = new BProdSku();
    private readonly static IProdMaterial _ProdMaterial = new BProdMaterial();
    private readonly static ILineManager _LineManger = new BLineManager();
    private readonly static IWmsOutOrderMaster _WmsOutOrderMaster = new BWmsOutOrderMaster();
    private readonly static IRcsEquipCuring _RcsEquipCuring = new BRcsEquipCuring();

    public BizTaskBean GetOutTaskByTaskId(long taskId)
    {
        var task = GetTaskByTaskId(taskId);
        if (task == null)
        {
            return null;
        }

        var taskCmd = _TaskCmd.GetTaskCmdByTaskId(task.Id.GetValueOrDefault());
        var loctionCmd = _RcsLocation.GetLocationById(taskCmd.TargetLoc.GetValueOrDefault());
        var skuId = task.SkuId.GetValueOrDefault();
        var productCode = _ProdProduct.GetCodeBySkuId(skuId);
        var material = _ProdMaterial.GetMaterialBySkuId(skuId);
        var outSize = decimal.ToInt32(material?.OutsideDiameter ?? 0M);
        var result = new BizTaskBean()
        {
            TaskNo = task.TaskNo,
            TargetLoc = taskCmd?.TargetLoc,
            TargetCmdPlcLoc = loctionCmd?.PlcCode,
            ProductCode = productCode,
            OutSize = outSize,
            TaskGroup = task.TaskGroup ?? 0,
        };
        return result;
    }
    public int UpdateTaskIsOutScannerByTaskNo(int taskNo)
    {
        var db = Db.Default;
        var result = db.WcsTasks.Where(t => t.TaskNo == taskNo).Update(new POWcsTask
        {
            IsOutScanner = 1,
        });
        db.SaveChanges();
        return result;

    }
    public int SyncScadaCrnTask()
    {
        WriteLog($"同步堆垛机开始执行aa", true);
        var db = Db.Default;
        //listScadaCrnTaskBean crnTasks = new ScadaCrnTaskBean();
        var forkTask1 = db.WcsTaskCmds.Join(db.RcsEquipCrns, f => f.EquipId, s => s.CrnFork1, (f, s) => new
        {

            f.TaskNo,
            s.Id,
            f.CmdStatus
        }).Where(t => t.CmdStatus == (int)EnumTaskCmdStatus.Executed).Select(t => new ScadaCrnTaskBean
        {
            Id = t.Id,
            TaskNo = t.TaskNo,
        }).ToList();
        WriteLog($"同步堆垛机开始执行bb", true);
        var forkTask2 = db.WcsTaskCmds.Join(db.RcsEquipCrns, f => f.EquipId, s => s.CrnFork2, (f, s) => new
        {

            f.TaskNo,
            s.Id,
            f.CmdStatus
        }).Where(t => t.CmdStatus == (int)EnumTaskCmdStatus.Executed).Select(t => new ScadaCrnTaskBean
        {
            Id = t.Id,
            TaskNo = t.TaskNo,
        }).ToList();
        WriteLog($"同步堆垛机开始执行cc", true);
        var crnIds = db.RcsEquipCrns.Select(t => t.Id).ToList();
        WriteLog($"同步堆垛机开始执行dd", true);
        //foreach (var crnId in crnIds)
        //{
        //    await AsyncFlushScadaBoxTasks(crnId ?? 0, forkTask1, forkTask2);
        //}
        //GetData().
        GetData().AsParallel().ForAll(crnId =>
        {
            WriteLog($"{crnId}开始执行1", true);
            ScadaBoxTaskParam crnTask = new();
            crnTask.LineCode = crnId.ToString();
            WriteLog($"{crnId}开始执行2", true);
            crnTask.TaskNo = forkTask1.Where(t => t.Id == crnId).FirstOrDefault()?.TaskNo ?? 0;
            crnTask.TaskNo2 = forkTask2.Where(t => t.Id == crnId).FirstOrDefault()?.TaskNo ?? 0;
            WriteLog($"{crnId}开始执行3", true);
            FlushScadaBoxTasks(crnTask);
            WriteLog($"{crnId}开始执行4", true);
        });
        //foreach (long crnId in GetData())
        //{
        //    WriteLog($"{crnId}开始执行1", true);
        //    ScadaBoxTaskParam crnTask = new();
        //    crnTask.LineCode = crnId.ToString();
        //    WriteLog($"{crnId}开始执行2", true);
        //    crnTask.TaskNo = forkTask1.Where(t => t.Id == crnId).FirstOrDefault()?.TaskNo ?? 0;
        //    crnTask.TaskNo2 = forkTask2.Where(t => t.Id == crnId).FirstOrDefault()?.TaskNo ?? 0;
        //    WriteLog($"{crnId}开始执行3", true);
        //    FlushScadaBoxTasks(crnTask);
        //    WriteLog($"{crnId}开始执行4", true);
        //}
        WriteLog($"同步堆垛机开始执行ee", true);
        return 1;
    }

    static List<long> GetData()
    {
        var db = Db.Default;
        var crns = db.RcsEquipCrns.Select(t => t.Id ?? 0).ToList();

        return crns;
    }

    int FlushScadaBoxTasks(ScadaBoxTaskParam param)
    {
        int result = -1;

        if (String.IsNullOrWhiteSpace(param?.LineCode))//线体编号必须有
        {
            return result;
        }

        var query = _LineManger.QueryScadaBoxTasksByLineCode(param.LineCode);

        if (query is null)//没有节点数据，添加
        {
            result = _LineManger.InsertToScadaBoxTasks(param);
        }
        else//已有节点数据，修改
        {
            result = _LineManger.UpdateScadaBoxTasksByLineCode(param);
        }

        return result;
    }

    async Task AsyncFlushScadaBoxTasks(long CrnId, List<ScadaCrnTaskBean> ForkTask1, List<ScadaCrnTaskBean> ForkTask2)
    {
        ScadaBoxTaskParam crnTask = new();
        crnTask.LineCode = CrnId.ToString(); ;
        crnTask.TaskNo = ForkTask1.Where(t => t.Id == CrnId).FirstOrDefault()?.TaskNo ?? 0;
        crnTask.TaskNo2 = ForkTask2.Where(t => t.Id == CrnId).FirstOrDefault()?.TaskNo ?? 0;
        FlushScadaBoxTasks(crnTask);
    }

    public int UpdateTaskAndCmdTargetLoc(long taskId, long targetLoc)
    {

        var db = Db.Default;
        var result = db.WcsTasks.Where(t => t.Id == taskId).Update(new POWcsTask
        {
            TargetLoc = targetLoc,
        });
        result += db.WcsTaskCmds.Where(t => t.TaskId == taskId).Update(new POWcsTaskCmd
        {
            TargetLoc = targetLoc,
        });
        db.SaveChanges();
        return result;
    }
    public BizTaskBeanV2 GetTaskByExecuteStartLoc(long StartLoc)
    {
        var db = Db.Default;
        ////WriteLog($"下传任务开始打印", true);
        var result = db.WcsTasks.Join(db.WcsTaskCmds, f => f.Id, s => s.TaskId, (f, s) => new
        {
            f.TaskNo,
            f.SkuId,
            f.TaskType,
            f.TargetLoc,
            f.CreateTime,
            f.TaskStatus,
            f.IsDownload,
            f.StartLoc,
            f.DirectDelivery,
            f.TaskGroup,
            CmdTargetLoc = s.TargetLoc,
        }).Where(t => t.TaskStatus < (int)EnumTaskStatus.Executed && t.IsDownload == (int)EnumTaskDown.NotDown && t.StartLoc == StartLoc && (t.TaskType == (int)EnumTaskType.Transportation || t.TaskType == (int)EnumTaskType.Abnormal || t.DirectDelivery == 1))
        .Join(db.ProdSkus, f => f.SkuId, s => s.Id, (f, s) => new
        {
            f.TaskNo,
            f.SkuId,
            f.TaskType,
            f.TargetLoc,
            f.CmdTargetLoc,
            f.CreateTime,
            s.MaterialId,
            s.SkuCode,
            f.TaskGroup,
        }).Join(db.ProdMaterials, f => f.MaterialId, s => s.Id, (f, s) => new
        {
            f.TaskNo,
            f.SkuId,
            f.TaskType,
            f.TargetLoc,
            f.CmdTargetLoc,
            f.CreateTime,
            f.MaterialId,
            f.SkuCode,
            f.TaskGroup,
            outSize = s.OutsideDiameter,
        }).Join(db.RcsLocations, f => f.TargetLoc, s => s.Id, (f, s) => new
        {

            f.TaskNo,
            f.SkuId,
            f.TaskType,
            f.TargetLoc,
            f.CmdTargetLoc,
            f.CreateTime,
            f.MaterialId,
            f.SkuCode,
            f.TaskGroup,
            f.outSize,
            TargetPlcLoc = s.PlcCode,
        }).Join(db.RcsLocations, f => f.CmdTargetLoc, s => s.Id, (f, s) => new BizTaskBeanV2()
        {

            TaskNo = f.TaskNo,
            TargetCmdPlcLoc = s.PlcCode,
            TargetPlcLoc = f.TargetPlcLoc,
            ProductCode = f.SkuCode,
            OutSize = decimal.ToInt32(f.outSize ?? 0),
            TaskType = f.TaskType ?? 0,
            CreateTime = f.CreateTime,
            TaskGroup = f.TaskGroup,
        }).OrderBy(t => t.CreateTime).FirstOrDefault();
        //var sql = result1.ToQueryString();
        ////WriteLog($"下传任务打印{sql}", true);
        //var result = result1.FirstOrDefault();
        ////WriteLog($"下传任务完成查询{result.TaskNo}", true);
        return result;
    }

    public BizTaskBeanV2 GetTaskByCmdExecuteStartLoc(long StartLoc)
    {
        var db = Db.Default;
        ////WriteLog($"下传任务开始打印", true);
        var result = db.WcsTasks.Join(db.WcsTaskCmds, f => f.Id, s => s.TaskId, (f, s) => new
        {
            f.TaskNo,
            f.SkuId,
            f.TaskType,
            f.TargetLoc,
            f.CreateTime,
            f.TaskStatus,
            f.IsDownload,
            s.StartLoc,
            f.DirectDelivery,
            CmdTargetLoc = s.TargetLoc,
            s.CmdStatus,
        }).Where(t => t.CmdStatus < (int)EnumTaskStatus.Executed && t.StartLoc == StartLoc && (t.TaskType == (int)EnumTaskType.Transportation || t.TaskType == (int)EnumTaskType.Abnormal || t.DirectDelivery == 1))
        .Join(db.ProdSkus, f => f.SkuId, s => s.Id, (f, s) => new
        {
            f.TaskNo,
            f.SkuId,
            f.TaskType,
            f.TargetLoc,
            f.CmdTargetLoc,
            f.CreateTime,
            s.MaterialId,
            s.SkuCode,
            f.CmdStatus,
        }).Join(db.ProdMaterials, f => f.MaterialId, s => s.Id, (f, s) => new
        {
            f.TaskNo,
            f.SkuId,
            f.TaskType,
            f.TargetLoc,
            f.CmdTargetLoc,
            f.CreateTime,
            f.MaterialId,
            f.SkuCode,
            outSize = s.OutsideDiameter,
            f.CmdStatus,
        }).Join(db.RcsLocations, f => f.TargetLoc, s => s.Id, (f, s) => new
        {

            f.TaskNo,
            f.SkuId,
            f.TaskType,
            f.TargetLoc,
            f.CmdTargetLoc,
            f.CreateTime,
            f.MaterialId,
            f.SkuCode,
            f.outSize,
            TargetPlcLoc = s.PlcCode,
            f.CmdStatus,
        }).Join(db.RcsLocations, f => f.CmdTargetLoc, s => s.Id, (f, s) => new BizTaskBeanV2()
        {

            TaskNo = f.TaskNo,
            TargetCmdPlcLoc = s.PlcCode,
            TargetPlcLoc = f.TargetPlcLoc,
            ProductCode = f.SkuCode,
            OutSize = decimal.ToInt32(f.outSize ?? 0),
            TaskType = f.TaskType ?? 0,
            CreateTime = f.CreateTime,
            CmdStatus = f.CmdStatus,
        }).OrderBy(t => t.CreateTime).FirstOrDefault();
        //var sql = result1.ToQueryString();
        ////WriteLog($"下传任务打印{sql}", true);
        //var result = result1.FirstOrDefault();
        ////WriteLog($"下传任务完成查询{result.TaskNo}", true);
        return result;
    }
    public List<BizTaskBeanV2> GetTaskByExecuteStartLocV3(long StartLoc)
    {
        var db = Db.Default;

        var result = db.WcsTasks.Join(db.WcsTaskCmds, f => f.Id, s => s.TaskId, (f, s) => new
        {
            f.TaskNo,
            f.SkuId,
            f.TaskType,
            f.TargetLoc,
            f.CreateTime,
            f.TaskStatus,
            f.IsDownload,
            f.StartLoc,
            f.DirectDelivery,
            CmdTargetLoc = s.TargetLoc,
        }).Where(t => t.TaskStatus < (int)EnumTaskStatus.Executed && t.IsDownload == (int)EnumTaskDown.NotDown && t.StartLoc == StartLoc && (t.TaskType == (int)EnumTaskType.Transportation || t.TaskType == (int)EnumTaskType.Abnormal || t.DirectDelivery == 1))
        .Join(db.ProdSkus, f => f.SkuId, s => s.Id, (f, s) => new
        {
            f.TaskNo,
            f.SkuId,
            f.TaskType,
            f.TargetLoc,
            f.CmdTargetLoc,
            f.CreateTime,
            s.MaterialId,
            s.SkuCode,
        }).Join(db.ProdMaterials, f => f.MaterialId, s => s.Id, (f, s) => new
        {
            f.TaskNo,
            f.SkuId,
            f.TaskType,
            f.TargetLoc,
            f.CmdTargetLoc,
            f.CreateTime,
            f.MaterialId,
            f.SkuCode,
            outSize = s.OutsideDiameter,
        }).Join(db.RcsLocations, f => f.TargetLoc, s => s.Id, (f, s) => new
        {

            f.TaskNo,
            f.SkuId,
            f.TaskType,
            f.TargetLoc,
            f.CmdTargetLoc,
            f.CreateTime,
            f.MaterialId,
            f.SkuCode,
            f.outSize,
            TargetPlcLoc = s.PlcCode,
        }).Join(db.RcsLocations, f => f.CmdTargetLoc, s => s.Id, (f, s) => new BizTaskBeanV2()
        {

            TaskNo = f.TaskNo,
            TargetCmdPlcLoc = s.PlcCode,
            TargetPlcLoc = f.TargetPlcLoc,
            ProductCode = f.SkuCode,
            OutSize = decimal.ToInt32(f.outSize ?? 0),
            TaskType = f.TaskType ?? 0,
            CreateTime = f.CreateTime,
        }).OrderBy(t => t.CreateTime).AsNoTracking().ToList();

        return result;
    }

    public BizTaskBean GetTaskBeanByProductCode(string productCode)
    {

        var db = Db.Default;
        //var prodSku = db.ProdSkus.Where(t => t.SkuCode == productCode).OrderByDescending(t => t.CreateTime).FirstOrDefault();

        var wcsSku = db.WcsTasks.Join(db.ProdSkus, f => f.SkuId, s => s.Id, (f, s) => new
        {
            f,
            s.MaterialId,
            s.SkuCode,
            s.CreateTime,
            skuId = s.Id,
        }).Where(t => t.SkuCode == productCode).OrderByDescending(t => t.CreateTime).FirstOrDefault();


        var task = wcsSku.f;
        var skuId = wcsSku.skuId;

        var materialId = wcsSku.MaterialId;

        var taskCmd = _TaskCmd.GetTaskCmdByTaskId(task.Id.GetValueOrDefault());

        var loction = _RcsLocation.GetLocationById(task.TargetLoc.GetValueOrDefault());

        var loctionCmdStart = _RcsLocation.GetLocationById(taskCmd.StartLoc.GetValueOrDefault());

        var loctionCmd = _RcsLocation.GetLocationById(taskCmd.TargetLoc.GetValueOrDefault());

        var material = _ProdMaterial.GetMaterialById(materialId ?? 0);

        var outSize = decimal.ToInt32(material?.OutsideDiameter ?? 0M);

        //var height = decimal.ToInt32(material?.MaterialHeight ?? 0M);

        return new BizTaskBean
        {
            Id = task.Id,
            TaskNo = task.TaskNo,
            StartLoc = task.StartLoc,
            StartCmdPlcLoc = loctionCmdStart?.PlcCode,
            TargetLoc = taskCmd?.TargetLoc,
            TargetPlcLoc = loction?.PlcCode,
            TargetCmdPlcLoc = loctionCmd?.PlcCode,
            CmdStatus = taskCmd.CmdStatus.GetValueOrDefault(),
            TaskGroup = task.TaskGroup,
            TaskGroupIndex = task.TaskGroupIndex,
            ProductCode = productCode,
            SkuId = skuId ?? 0,
            OutSize = outSize,
            //Height = height,
            TaskType = task.TaskType,
        };
    }

    public BizTaskBean GetTaskBeanByStartLoc(long startLoc)
    {
        var db = Db.Default;

        var locs = _RcsLocation.GetAllLocationsByType((int)EnumLocType.AbnormalInLoc);
        if (locs.Count == 0)
        {
            return null;
        }
        var loc = locs.FirstOrDefault();
        var taskId = loc.TaskId ?? 0;
        if (taskId == 0)
        {
            return null;
        }

        var productCode = loc.ProductCode;

        var prodSku = db.ProdSkus.Where(t => t.SkuCode == productCode).OrderByDescending(t => t.CreateTime).FirstOrDefault();

        var wcsSku = db.WcsTasks.Join(db.ProdSkus, f => f.SkuId, s => s.Id, (f, s) => new
        {
            f,
            s.MaterialId,
            s.SkuCode,
            s.CreateTime,
            skuId = s.Id,
        }).Where(t => t.SkuCode == productCode).OrderByDescending(t => t.CreateTime).FirstOrDefault();

        var task = wcsSku.f;
        var skuId = wcsSku.skuId;

        var materialId = wcsSku.MaterialId;

        var taskCmd = _TaskCmd.GetTaskCmdByTaskId(task.Id.GetValueOrDefault());
        if (taskCmd is null)
        {
            return null;
        }

        var loction = _RcsLocation.GetLocationById(task.TargetLoc.GetValueOrDefault());

        var loctionCmdStart = _RcsLocation.GetLocationById(taskCmd.StartLoc.GetValueOrDefault());

        var loctionCmd = _RcsLocation.GetLocationById(taskCmd.TargetLoc.GetValueOrDefault());

        var material = _ProdMaterial.GetMaterialById(materialId ?? 0);

        var outSize = decimal.ToInt32(material?.OutsideDiameter ?? 0M);

        return new BizTaskBean
        {
            Id = task.Id,
            TaskNo = task.TaskNo,
            StartLoc = task.StartLoc,
            StartCmdPlcLoc = loctionCmdStart?.PlcCode,
            TargetLoc = taskCmd?.TargetLoc,
            TargetPlcLoc = loction?.PlcCode,
            TargetCmdPlcLoc = loctionCmd?.PlcCode,
            CmdStatus = taskCmd.CmdStatus.GetValueOrDefault(),
            TaskGroup = task.TaskGroup,
            TaskGroupIndex = task.TaskGroupIndex,
            ProductCode = productCode,
            SkuId = skuId ?? 0,
            OutSize = outSize,
            TaskType = task.TaskType,
        };
    }

    public BizTaskBean GetEmsTaskBeanByProductCode(string productCode)
    {

        var db = Db.Default;
        //var prodSku = db.ProdSkus.Where(t => t.SkuCode == productCode).OrderByDescending(t => t.CreateTime).FirstOrDefault();


        var wcsSku = db.WcsTasks.Join(db.ProdSkus, f => f.SkuId, s => s.Id, (f, s) => new
        {
            f,
            s,
        }).Where(t => t.s.SkuCode == productCode).OrderByDescending(t => t.s.CreateTime).FirstOrDefault();

        var task = wcsSku.f;
        var sku = wcsSku.s;

        var taskCmd = _TaskCmd.GetTaskCmdByTaskId(task.Id.GetValueOrDefault());

        var loction = _RcsLocation.GetLocationById(task.TargetLoc.GetValueOrDefault());

        var loctionCmdStart = _RcsLocation.GetLocationById(taskCmd.StartLoc.GetValueOrDefault());

        var loctionCmd = _RcsLocation.GetLocationById(taskCmd.TargetLoc.GetValueOrDefault());

        var material = _ProdMaterial.GetMaterialById(sku.MaterialId ?? 0);

        var outSize = decimal.ToInt32(material?.OutsideDiameter ?? 0M);

        //var height = decimal.ToInt32(material?.MaterialHeight ?? 0M);
        return new BizTaskBean
        {
            Id = task.Id,
            TaskNo = task.TaskNo,
            StartLoc = task.StartLoc,
            StartCmdPlcLoc = loctionCmdStart?.PlcCode,
            TargetLoc = taskCmd?.TargetLoc,
            TargetPlcLoc = loction?.PlcCode,
            TargetCmdPlcLoc = loctionCmd?.PlcCode,
            CmdStatus = taskCmd.CmdStatus.GetValueOrDefault(),
            TaskGroup = task.TaskGroup,
            TaskGroupIndex = task.TaskGroupIndex,
            ProductCode = productCode,
            SkuId = sku.Id ?? 0,
            OutSize = outSize,
            //Height = height,
            TaskType = task.TaskType,
        };
    }

    public POWcsTask GetTaskByProductCode(string productCode)
    {
        var skuId = _ProdProduct.GetSkuIdByCode(productCode);

        // var skuId = _ProdSku.GetProdSkuBySkuCode(productCode)?.Id;

        var db = Db.Default;
        var result = db.WcsTasks
            .Where(t => t.SkuId == skuId).OrderBy(t => t.CreateTime)
            .FirstOrDefault();
        return result;
    }

    public POWcsTask GetTaskByProductCodev2(string productCode)
    {
        //var skuId = _ProdProduct.GetSkuIdByCode(productCode);

        var skuId = _ProdSku.GetProdSkuBySkuCode(productCode)?.Id ?? 0;
        if (skuId == 0)
        {
            return null;
        }

        var db = Db.Default;
        var result = db.WcsTasks
            .Where(t => t.SkuId == skuId).OrderBy(t => t.CreateTime)
            .FirstOrDefault();
        return result;
    }

    public long GetInTaskIdByRemark(string remark)
    {
        var db = Db.Default;
        var result = db.WcsTasks
            .Where(t => t.RemarkMemo.Contains(remark) && t.TaskType != 2 && t.TaskType != 5)
            .FirstOrDefault().Id ?? 0;
        return result;
    }
    public POWcsTask GetEmsTaskByProductCode(string productCode)
    {
        POWcsTask result = new();
        try
        {
            //var skuId = _ProdProduct.GetSkuIdByCode(productCode);
            WriteLog($"条码{productCode}开始查找任务", true);
            var db = Db.Default;
            WriteLog($"条码{productCode}开始查找任务1111", true);
            //var skuIds = _ProdSku.GetProdSkuListBySkuCode(productCode).Select(t => t.Id);
            //WriteLog($"条码{productCode}开始查找任务11,返回skudIds{skuIds.ToJson()}", true);

            result = db.WcsTasks.Join(db.ProdSkus, f => f.SkuId, s => s.Id, (f, s) => new
            {
                WcsTasks = f,
                s.SkuCode,
            }).Where(t => t.WcsTasks.TaskType > (int)EnumTaskType.Warehousing && t.SkuCode == productCode)
            .OrderByDescending(f => f.WcsTasks.CreateTime).Select(t => t.WcsTasks).FirstOrDefault();
            //WriteLog($"条码{productCode}开始查找任务222,result{result.ToJson()}", true);

            //var results = tasks.Join(skuIds, f => f.SkuId, s => s, (f, s) => f)
            //   .OrderByDescending(t => t.CreateTime).ToList();
            ////if (results.Count > 1)
            ////{
            ////WriteLog($"{productCode}ems下传位任务skus{results.ToJson()}", true);
            ////}
            //var result = results.FirstOrDefault();
        }
        catch (Exception ex)
        {
            WriteLog($"条码{productCode}开始查找任务失败，{ex.ToString()}", true);
        }

        return result;
    }




    public POWcsTask GetTaskByExecuteProductCode(string productCode)
    {
        var skuId = _ProdProduct.GetSkuIdByCode(productCode);
        var db = Db.Default;
        var result = db.WcsTasks
            .Where(t => t.SkuId == skuId && t.TaskStatus < (int)EnumTaskStatus.Executed).OrderBy(t => t.CreateTime)
            .FirstOrDefault();
        return result;
    }
    public long GetTaskIdByProductCode(string productCode) => GetTaskByProductCode(productCode)?.Id ?? 0;
    public bool HasTaskByProductCode(string productCode) => GetTaskByProductCode(productCode) != null;

    public long CreateOutAbnormalTask(long startLoc, long skuId, string remark, POWcsTask task, int taskNo = 0)
    {
        var abnormal = _WcsNetAbnormal.GetWcsNetAbnormalByStartLoc(startLoc);
        if (abnormal is null)
        {
            return 0;
        }
        var targetLoc = abnormal.TargetLoc.GetValueOrDefault();
        long startEquip = _WcsEquipLoc.GetEquipIdByLocId(startLoc); // 获取开始设备
        long targetEquip = _WcsEquipLoc.GetEquipIdByLocId(targetLoc); // 获取目标设备
        if (taskNo == 0)
        {
            taskNo = K8.LSF.Client.CodeValue(new DateTime(), "TaskNo").ToInt(0);
        }
        POWcsTask pOWcsTask = new()
        {
            Id = XID.Nextval,
            TaskNo = taskNo,
            SkuId = skuId,
            StartEquip = startEquip,
            StartLoc = startLoc,
            CurrentEquip = startEquip,
            CurrentLoc = startLoc,
            TargetEquip = targetEquip,
            TargetLoc = targetLoc,
            TaskStatus = (int?)EnumTaskStatus.Executable,
            TaskType = (int)EnumTaskType.Abnormal,
            IsAbnormal = true,
            RemarkMemo = remark,
            TooltipMemo = remark,
            MasterId = task?.MasterId ?? 0,
            SummaryId = task?.SummaryId ?? 0,

        };

        var db = Db.Default;
        db.WcsTasks.Insert(pOWcsTask);
        return pOWcsTask.Id.GetValueOrDefault();
    }
    public List<POWcsTask> GetTaskByType(int type)
    {
        var db = Db.Default;
        var result = db.WcsTasks
            .Where(t => t.TaskType == type)
            .OrderBy(t => t.CreateTime)
            .ToList();
        return result;
    }

    public List<long> GetTaskByCurrentEquip(List<long?> emsIds, int type)
    {
        var db = Db.Default;
        var targetlocs = new List<long>();
        foreach (var emsId in emsIds)
        {
            var result = db.WcsTasks.Where(t => t.TaskType == type && t.CurrentEquip == emsId).Select(t => t.TargetLoc.GetValueOrDefault()).ToList();
            //targetlocs = targetlocs.Concat(result).ToList();
            targetlocs.AddRange(result);
        }

        //var result = db.WcsTasks
        //    .Where(t => t.TaskType == type)
        //    .OrderBy(t => t.CreateTime)
        //    .ToList();
        return targetlocs;
    }

    public List<POWcsTask> GetHasSummaryTask()
    {
        var db = Db.Default;
        var result = db.WcsTasks
            .Where(t => t.SummaryId != null && t.SummaryId != 0)
            .OrderBy(t => t.CreateTime)
            .ToList();
        return result;
    }
    //OLDTODO 【已解决】分成入库出库两个函数调用， 添加一个状态判断 < 2 [可执行]
    public List<POWcsTask> GetIOExecutableWcsTasksByType(EnumTaskType enumTaskType) => enumTaskType switch
    {   //下面有改动 lsq
        EnumTaskType.Warehousing => GetTaskByType((int)EnumTaskType.Warehousing).Where(t => t.TaskStatus < (int)EnumTaskStatus.Executed).ToList(),
        EnumTaskType.Exwarehouse => GetTaskByType((int)EnumTaskType.Exwarehouse).Where(t => t.TaskStatus < (int)EnumTaskStatus.Executed).ToList(),
        _ => new List<POWcsTask>(),
    };
    public List<POWcsTask> GetAllTasksByTargetLoc(long targetLoc)
    {
        var db = Db.Default;
        var result = db.WcsTasks
            .Where(t => t.TargetLoc == targetLoc)
            .ToList();
        return result;
    }
    public int GetTaskCountByTargetLoc(long targetLoc) => GetAllTasksByTargetLoc(targetLoc).Count;
    public bool GetHasTaskByTargetLoc(long targetLoc)
    {
        var location = _RcsLocation.GetLocationById(targetLoc);
        if (location is null)//|| location.MaterialId is not null
        {
            return true;
        }

        if (location.LocHasSku == 1)
        {
            return true;
        }

        var flag = GetAllTasksByTargetLoc(targetLoc).Count != 0;
        if (flag)
        {
            return true;
        }
        return false;
    }
    public POWcsTask GetTaskBySkuId(long skuId)
    {
        var db = Db.Default;
        var result = db.WcsTasks
            .Where(t => t.SkuId == skuId)
            .FirstOrDefault();
        return result;
    }

    public long GetTaskIdBySkuId(long skuId)
    {
        var db = Db.Default;
        var result = db.WcsTasks
            .Where(t => t.SkuId == skuId).Select(t => t.Id)
            .FirstOrDefault() ?? 0;
        return result;
    }

    public TaskCmdBean GetTaskCmdBeanBySkuId(long skuId)
    {
        var db = Db.Default;
        var result = db.WcsTasks.Join(db.WcsTaskCmds, f => f.Id, s => s.TaskId, (f, s) => new TaskCmdBean
        {
            CmdTargetLoc = s.TargetLoc ?? 0,
            CmdStatus = s.CmdStatus ?? 0,
            CmdStartLoc = s.StartLoc ?? 0,
            TaskId = f.Id ?? 0,
            SkuId = f.SkuId ?? 0,
        })
            .Where(t => t.SkuId == skuId)
            .FirstOrDefault();
        return result;
    }
    public List<POWcsTask> GetTasksByGroupNo(long groupNo)
    {
        var db = Db.Default;
        var result = db.WcsTasks
            .Where(t => t.TaskGroup == groupNo)
            .ToList();
        return result;
    }
    public string GetPoductCodeByTaskNo(int taskNo)
    {
        var db = Db.Default;
        var result = db.WcsTasks.Join(db.ProdSkus, f => f.SkuId, s => s.Id, (f, s) => new
        {
            taskNo = f.TaskNo,
            createTime = s.CreateTime,
            skuCode = s.SkuCode,
        }).Where(t => t.taskNo == taskNo).OrderByDescending(t => t.createTime).FirstOrDefault()?.skuCode;

        return result;
    }
    public List<POWcsTask> GetTasksByGroupNoAndScanner(long groupNo, long scannerLoc)
    {
        var db = Db.Default;
        var result = db.WcsTasks
            .Where(t => t.TaskGroup == groupNo && t.SpinScanId == scannerLoc)
            .ToList();
        return result;
    }
    public POWcsTask GetTasksByScannerAndTime(long emsLoc, long scannerLoc, DateTime scannerTime)
    {
        var db = Db.Default;
        var result = db.WcsTasks.Join(db.WcsTaskCmds, f => f.Id, s => s.TaskId, (f, s) => new
        {
            WcsTasks = f,
            WcsTaskCmds = s,
        })
            .Where(t => t.WcsTasks.SpinScanId == scannerLoc && t.WcsTaskCmds.TargetLoc == emsLoc && t.WcsTasks.SpinTime > scannerTime).OrderBy(t => t.WcsTasks.SpinTime).Select(t => t.WcsTasks)
            .FirstOrDefault();
        return result;
    }


    public List<POWcsTask> GetTasksByScannerAndEmsLoc(long emsLoc, long scannerLoc)
    {
        var db = Db.Default;
        var result = db.WcsTasks.Join(db.WcsTaskCmds, f => f.Id, s => s.TaskId, (f, s) => new
        {
            WcsTasks = f,
            WcsTaskCmds = s,
        })
            .Where(t => t.WcsTasks.SpinScanId == scannerLoc && t.WcsTaskCmds.TargetLoc == emsLoc).OrderBy(t => t.WcsTasks.SpinTime).Select(t => t.WcsTasks)
            .ToList();
        return result;
    }

    public POWcsTask GetTaskByTaskId(long taskId)
    {
        var db = Db.Default;
        var result = db.WcsTasks
            .Where(t => t.Id == taskId).AsNoTracking()
            .FirstOrDefault();
        return result;
    }

    public int UpdateTaskRemark(long taskId, string remark)
    {
        var db = Db.Default;

        var subStr = remark.Substring(0, (remark.Length < 900 ? remark.Length : 900));

        var result = db.WcsTasks
            .Where(t => t.Id == taskId)
            .Update(new POWcsTask
            {
                RemarkMemo = subStr,
            });
        return db.SaveChanges();
    }
    public int UpdateTaskTargetLocRemark(long taskId, long targetLoc, string remark)
    {
        var db = Db.Default;
        var result = db.WcsTasks
            .Where(t => t.Id == taskId)
            .Update(new POWcsTask
            {
                TargetLoc = targetLoc,
                RemarkMemo = remark,
            });
        return db.SaveChanges();
    }

    public POWcsTask GetExecutedTaskByTaskId(long taskId)
    {
        var result = GetTaskByTaskId(taskId);
        return result.TaskStatus < (int)EnumTaskStatus.Finish ? result : null;
    }
    public long GetTargetIdByTaskId(long taskId) => GetTaskByTaskId(taskId)?.TargetLoc ?? 0;

    public POWcsTask GetTaskByTaskNo(int taskNo)
    {
        //WriteLog($"任务{taskNo}GetTaskByTaskNo728", true);
        if (taskNo == 0)
        {
            return null;
        }
        var result = new POWcsTask();
        var db = Db.Default;
        {
            //WriteLog($"任务{taskNo}GetTaskByTaskNo735,{db.ContextId}", true);
            result = db.WcsTasks
               .Where(t => t.TaskNo == taskNo)
               .FirstOrDefault();
        }
        // WriteLog($"任务{taskNo}GetTaskByTaskNo739", true);
        return result;
    }

    public POWcsTask GetEmsTaskByTaskNo(int taskNo)
    {

        if (taskNo == 0)
        {
            return null;
        }
        var result = new POWcsTask();
        var db = Db.Default;


        result = db.WcsTasks
           .Where(t => t.TaskNo == taskNo && t.TaskType > (int)EnumTaskType.Warehousing)
           .OrderByDescending(f => f.CreateTime).FirstOrDefault();

        // WriteLog($"任务{taskNo}GetTaskByTaskNo739", true);
        return result;
    }
    public POWcsTask GetTaskBySummaryId(long summaryId)
    {
        var db = Db.Default;
        var result = db.WcsTasks
            .Where(t => t.SummaryId == summaryId).OrderByDescending(t => t.CreateTime)
            .FirstOrDefault();
        return result;
    }

    public int UpdateCallDelete(long summaryId)
    {
        var db = Db.Default;
        var result = db.WcsTasks
            .Where(t => t.SummaryId == summaryId).Update(new POWcsTask
            {
                CallDelete = 1,
                RemarkMemo = "流水号不同删除",
            });
        return db.SaveChanges();
    }
    public int UpdateSpinScanId(long locId, long taskNo)
    {
        var db = Db.Default;
        var result = db.WcsTasks
            .Where(t => t.TaskNo == taskNo).FirstOrDefault();
        if (result is not null)
        {
            result.SpinScanId = locId;
            result.SpinTime = DateTime.Now;
        }
        return db.SaveChanges();
    }
    public POWcsTask GetExecutableTaskByTaskNo(int taskNo)
    {
        var result = GetTaskByTaskNo(taskNo);
        if (result == null)
        {
            return null;
        }
        else
        {
            var cmdResult = _TaskCmd.GetTaskCmdByTaskId(result.Id.GetValueOrDefault());
            if (cmdResult != null && cmdResult.CmdStatus < (int)EnumTaskCmdStatus.Executed)
            {
                return result;
            }

        }
        return null;
    }
    public POWcsTask GetDistributionLocByTaskNo(int taskNo)
    {
        var result = GetTaskByTaskNo(taskNo);
        return result?.TaskStatus == (int)EnumTaskStatus.Executed ? result : null;
    }
    public POWcsTask GetExecutedByTaskNo(int taskNo)
    {

        var result = GetTaskByTaskNo(taskNo);

        return result;

    }
    public POWcsTask GetExecutedTaskByTaskNo(int taskNo)
    {
        var result = GetTaskByTaskNo(taskNo);
        return result.TaskStatus == (int)EnumTaskStatus.Executed ? result : null;
    }

    //public POWcsTask GetLastTaskByLocIdV2(long locId, int type, long materialId)
    //{
    //    var db = Db.Default;
    //    var result = db.WcsTasks
    //        .Where(t => t.StartLoc == locId && t.TaskType == type).OrderByDescending(t => t.CreateTime)
    //        .FirstOrDefault();

    //    if (result is null)
    //    {
    //        return result;
    //    }

    //    var prodSkuProduct = _ProdSkuProduct.GetProdSkuProductBySkuId(result.SkuId);
    //    if (prodSkuProduct?.MaterialId != materialId)
    //    {
    //        return null;
    //    }

    //    return result;
    //}

    /// <summary>
    /// 查找堆垛机规律【奇数物料相同——偶数——奇数物料不同】
    /// </summary>
    /// <param name="locId"></param>
    /// <param name="type"></param>
    /// <param name="materialId"></param>
    /// <returns></returns>
    public (POWcsTask, List<long>) GetLastTaskByLocId(long locId, int type, long materialId)
    {

        var db = Db.Default;
        var targetLocIds = db.WcsAsrsNetInputs.Where(t => t.StartLoc == locId && t.UseFlag == 1).Select(t => t.TargetLoc).ToList();
        //var targetLocIds = wcsAsrsNetInputs.Select(t => t.TargetLoc).ToList();
        var tasks = db.WcsTasks.ToList();
        var taskCount = tasks
            .Where(t => t.StartLoc == locId && targetLocIds.Contains(t.TargetLoc) && t.TaskType == type)
            .GroupBy(t => new { t.TargetEquip, t.TargetLoc })
            .Select(t => new
            {
                // 取开始位是此扫描仪的所有放胎位
                TargetEquip = t.Key.TargetEquip,
                TargetLoc = t.Key.TargetLoc,
                // 此放胎位的任务数
                Count = t.Count(),
                // 取这个放胎位最近的一次任务
                Task = t.OrderByDescending(t => t.CreateTime).FirstOrDefault(),
            }).ToList();

        // 开始位是当前扫描仪 输送任务 创建时间倒序排序  奇数
        var taskOdd = taskCount.Where(t => t.Count % 2 == 1).Select(t => t.Task).ToList();

        // 奇数 SkuID
        var taskOddSkuIds = taskOdd.Where(t => t is not null).Select(t => t.SkuId.GetValueOrDefault()).ToList();

        // 奇数 物料相同 SkuID 【优先】
        //var taskMaterial = _ProdSkuProduct.GetProdSkuProductBySkuIds(taskOddSkuIds).Where(t => t.MaterialId == materialId).Select(t => t.SkuId).ToList();
        // var taskMaterial = _ProdSkuProduct.GetInWarehouseProdSkuProductBySkuIds(taskOddSkuIds).Where(t => t.MaterialId == materialId).Select(t => t.SkuId).ToList();
        var taskMaterial = _ProdSkuProduct.GetProdSkuProductBySkuIdsAndMaterial(taskOddSkuIds, materialId).ToList();


        // 数量少优先
        var taskMaterialTask = taskCount.Where(t => taskMaterial.Contains(t.Task.SkuId)).OrderBy(t => t.Count).Select(t => t.Task).FirstOrDefault();

        // 所有奇数任务 最后一个任务 入库放胎位
        var locIds = taskOdd.Where(t => t is not null).Select(t => t.TargetLoc).ToList();

        // 所有奇数堆垛机
        //var crnIds = _WcsAsrsCrnInput.GetWcsAsrsCrnInputs()
        //    .Where(t => locIds.Contains(t.InputLoc1) || locIds.Contains(t.InputLoc2))
        //    .Select(t => t.CrnId.GetValueOrDefault())
        //    .Distinct()
        //    .ToList();
        var crnIds = _WcsAsrsCrnInput.GetWcsAsrsCrnInputsByLocIds(locIds);


        if (taskMaterialTask is null)
        {
            // 所有奇数堆垛机
            return (null, crnIds);
        }
        else
        {
            // 货叉任务是奇数 物料也相同  取上次执行的任务
            return (taskMaterialTask, crnIds);
        }
    }


    public List<TaskGroupCount> GetMaterialTaskGroup()
    {
        var db = Db.Default;
        var result = db.WcsTasks.Join(db.ProdSkus, f => f.SkuId, s => s.Id, (f, s) => new { TargetLoc = f.TargetLoc, MaterialId = s.MaterialId })
            .GroupBy(s => s.TargetLoc)
            .Select(t => new TaskGroupCount
            {
                LocId = t.Key,
                Count = t.Count(),
            }).ToList();
        return result;
    }
    public List<TaskGroupCount> GetTargetLocTaskGroup()
    {
        var db = Db.Default;
        var result = db.WcsTasks.GroupBy(t => t.TargetLoc)
            .Select(t => new TaskGroupCount
            {
                LocId = t.Key.Value,
                Count = t.Count()
            }).ToList();
        return result;
    }
    public List<TaskGroupCount> GetExecutedTargetLocTaskGroup()
    {
        var db = Db.Default;
        var result = db.WcsTasks.Where(t => t.TaskStatus == (int)EnumTaskStatus.Executed).GroupBy(t => t.TargetLoc)
            .Select(t => new TaskGroupCount
            {
                LocId = t.Key.Value,
                Count = t.Count()
            }).ToList();
        return result;
    }

    public List<TaskGroupCount> GetTargetLocTaskGroupNoTaskIds(List<long> taskIds)
    {
        return GetTargetLocTaskGroup();
        var db = Db.Default;
        var result = db.WcsTasks.GroupBy(t => t.TargetLoc)
            .Select(t => new TaskGroupCount
            {
                LocId = t.Key.Value,
                Count = t.Where(s => !taskIds.Contains(s.Id.GetValueOrDefault())).Count()
            }).ToList();
        return result;
    }
    public List<TaskGroupCount> GetExecutedTargetLocTaskGroupNoTaskIds(List<long> taskIds)
    {
        return GetExecutedTargetLocTaskGroup();
        var db = Db.Default;
        var result = db.WcsTasks.Where(t => t.TaskStatus == (int)EnumTaskStatus.Executed).GroupBy(t => t.TargetLoc)
            .Select(t => new TaskGroupCount
            {
                LocId = t.Key.Value,
                Count = t.Where(s => !taskIds.Contains(s.Id.GetValueOrDefault())).Count()
            }).ToList();
        return result;
    }
    public List<TaskGroupCount> GetOutLocTaskGroup()
    {
        var db = Db.Default;
        var result = db.WcsTasks.Where(t => t.HouseOutputLoc != null).GroupBy(t => t.HouseOutputLoc)
            .Select(t => new TaskGroupCount
            {
                LocId = t.Key.Value,
                Count = t.Count()
            }).ToList();
        return result;
    }


    public List<CrnTaskCount> GetTaskInputCount(List<POWcsAsrsCrnInput> wcsAsrsCrnInputs)
    {
        // 到堆垛机放货位 任务汇总数量
        var taskCount = GetTargetLocTaskGroup();

        // 放货位数量[未执行]
        var startTaskCount = GetStartLocExecutableTaskGroup();

        // 堆垛机汇总数量
        var crnTaskCounts = new List<CrnTaskCount>();
        wcsAsrsCrnInputs.ForEach(item =>
        {
            var crnTask = crnTaskCounts.Where(t => t.CrnId == item.CrnId && t.AreaId == item.AreaId).FirstOrDefault();
            var targetLocCount = taskCount.Where(t => t.LocId == item.InputLoc1 || t.LocId == item.InputLoc2).Sum(t => t.Count);
            var startLoc = startTaskCount.Where(t => t.LocId == item.InputLoc1 || t.LocId == item.InputLoc2).Sum(t => t.Count);

            if (crnTask is null)
            {
                crnTaskCounts.Add(new()
                {
                    CrnId = item.CrnId.GetValueOrDefault(),
                    AreaId = item.AreaId.GetValueOrDefault(),
                    Count = targetLocCount + startLoc,
                    MaxCount = item.TaskCount.GetValueOrDefault(),
                });
            }
            else
            {
                crnTask.Count = crnTask.Count + targetLocCount + startLoc;
            }
        });
        return crnTaskCounts;
    }
    public List<TaskGroupCount> GetStartLocTaskGroup()
    {
        var db = Db.Default;
        var result = db.WcsTasks.GroupBy(t => t.StartLoc)
            .Select(t => new TaskGroupCount
            {
                LocId = t.Key.Value,
                Count = t.Count()
            }).ToList();
        return result;
    }
    public List<TaskGroupCount> GetStartLocExecutableTaskGroup()
    {
        var db = Db.Default;
        var result = db.WcsTasks.Where(t => t.TaskStatus == (int)EnumTaskStatus.Executable)
            .GroupBy(t => t.StartLoc)
            .Select(t => new TaskGroupCount
            {
                LocId = t.Key.Value,
                Count = t.Count()
            }).ToList();
        return result;
    }
    public POWcsTask GetTaskByStartLoc(long startLoc)
    {
        var db = Db.Default;
        var result = db.WcsTasks.Where(t => t.StartLoc == startLoc).FirstOrDefault();
        return result;
    }

    public List<POWcsTask> GetExecutableTasksByLocId(long locId)
    {
        var db = Db.Default;
        var result = db.WcsTasks.Join(db.WcsTaskCmds, a => a.Id, b => b.TaskId, (a, b) => new
        {
            Task = a,
            Cmd = b,
        })
            .Where(t => t.Cmd.StartLoc == locId && t.Cmd.CmdStatus < (int)EnumTaskStatus.Executed)
            .OrderByDescending(t => t.Cmd.CreateTime)
            .Select(t => t.Task)
            .ToList();
        return result;
    }
    public long GetExecutableTaskIdkByLocId(long locId) => GetExecutableTasksByLocId(locId).FirstOrDefault()?.Id ?? 0;
    public POWcsTask GetExecutableTaskByLocId(long locId) => GetExecutableTasksByLocId(locId).FirstOrDefault();

    public POWcsTask CreateTask(TaskDTO taskDTO)
    {
        var startLoc = taskDTO.StartLoc;
        var targetLoc = taskDTO.TargetLoc;
        var type = taskDTO.Type;
        var startEquip = taskDTO.StartEquip;
        var targetEquip = taskDTO.TargetEquip;
        var skuId = taskDTO.SkuId;
        var remark = taskDTO.Remark;
        var directDelivery = taskDTO.DirectDelivery;
        var taskNo = taskDTO.TaskNo;
        var taskStatus = taskDTO.Status;
        if (startLoc == 0 || targetLoc == 0)
        {
            return null;
        }
        //如果传进来的参数不是已执行 则任务状态为可执行
        if (taskStatus != (int)EnumTaskStatus.Executed)
        {
            taskStatus = (int)EnumTaskStatus.Executable;
        }
        if (!Enum.IsDefined(typeof(EnumTaskType), type))
        {
            return null;
        }
        var currentLoc = startLoc;
        if (startEquip == 0)
        {
            startEquip = _WcsEquipLoc.GetEquipIdByLocId(startLoc); // 获取开始设备
        }
        else
        {
            currentLoc = _WcsEquipLoc.GetLocIdByEquipId(startEquip.GetValueOrDefault());
        }
        if (targetEquip == 0)
        {
            targetEquip = _WcsEquipLoc.GetEquipIdByLocId(targetLoc); // 获取目标设备
        }

        // 类型转换
        var isAbnormal = false;
        if (type == (int)EnumTaskType.Abnormal)
        {
            //type = (int)EnumTaskType.Warehousing;
            isAbnormal = true;
        }

        if (taskNo == 0)
        {
            taskNo = K8.LSF.Client.CodeValue(new DateTime(), "TaskNo").ToInt(0);//new Random(999999).Next();
        }
        POWcsTask pOWcsTask = new()
        {
            Id = XID.Nextval,
            TaskNo = taskNo,
            SkuId = skuId,
            StartEquip = startEquip,
            StartLoc = startLoc,
            CurrentEquip = startEquip,
            CurrentLoc = currentLoc,
            TargetEquip = targetEquip,
            TargetLoc = targetLoc,
            TaskStatus = taskStatus,
            TaskType = type,
            IsAbnormal = isAbnormal,
            RemarkMemo = remark,
            TooltipMemo = remark,

            DirectDelivery = directDelivery,
        };

        var db = Db.Default;
        db.WcsTasks.Insert(pOWcsTask);
        return pOWcsTask;
    }

    public POWcsTaskCmd CreateEmsEmptyTaskAndCmd(long startLoc, long targetLoc, long startEquip)
    {

        POWcsTask task = new()
        {
            Id = XID.Nextval,
            TaskNo = K8.LSF.Client.CodeValue(new DateTime(), "TaskNo").ToInt(0),
            SkuId = 0,
            StartEquip = startEquip,
            StartLoc = startLoc,
            CurrentEquip = startEquip,
            CurrentLoc = startLoc,
            TargetEquip = startEquip,
            TargetLoc = targetLoc,
            TaskStatus = (int)EnumTaskStatus.Executable,
            TaskType = (int)EnumTaskType.EmsEmpty,
        };
        var db = Db.Default;
        db.WcsTasks.Insert(task);
        if (task is null)
        {
            return null;
        }
        var taskCmd = _TaskCmd.CreateTaskCmd(new()
        {
            TaskId = task.Id,
            TaskNo = task.TaskNo,
            TaskType = task.TaskType,
            EquipId = task.StartEquip,
            StartLoc = task.StartLoc,
            CurrentLoc = task.CurrentLoc,
            TargetLoc = task.TargetLoc,
            CmdStatus = (int)EnumTaskCmdStatus.Executable,
            CmdType = task.TaskType,
        });
        db.WcsTaskCmds.Insert(taskCmd);

        return taskCmd;


    }

    public void EditTaskType(long taskId, int type, long equipId)
    {
        var db = Db.Default;
        //var task = db.WcsTasks.Where(x => x.Id == taskId).FirstOrDefault();
        //if (task is null)
        //{
        //    return;
        //}
        //task.TaskType = type;
        db.WcsTasks.Where(t => t.Id == taskId).Update(new POWcsTask
        {
            CurrentEquip = equipId,
            TaskType = type
        });
        db.SaveChanges();
    }
    /// <summary>
    /// 修改入库任务创建入库指令
    /// </summary>

    /// <returns></returns>
    public TaskInfoBean EditTaskAndCreateCmd(TaskDTO taskDTO)
    {

        var taskId = taskDTO.TaskId;
        var targetLoc = taskDTO.TargetLoc;
        var status = taskDTO.Status;
        var type = taskDTO.Type;
        var startEquip = taskDTO.StartEquip;
        var targetEquip = taskDTO.TargetEquip;
        var startLoc = taskDTO.StartLoc;
        var groupNo = taskDTO.GroupNo;
        var groupIndex = taskDTO.GroupIndex;

        var currentLoc = startLoc;
        if (startEquip == 0)
        {
            startEquip = _WcsEquipLoc.GetEquipIdByLocId(startLoc); // 获取开始设备
        }
        else
        {
            currentLoc = _WcsEquipLoc.GetLocIdByEquipId(startEquip.GetValueOrDefault());
        }
        if (targetEquip == 0)
        {
            targetEquip = _WcsEquipLoc.GetEquipIdByLocId(targetLoc); // 获取目标设备
        }

        var db = Db.Default;
        var task = db.WcsTasks.Where(x => x.Id == taskId).FirstOrDefault();
        if (task is null)
        {
            return null;
        }

        // 创建指令
        var cmd = _TaskCmd.GetTaskCmdByTaskNo(task.TaskNo.GetValueOrDefault());
        var taskCmd = new POWcsTaskCmd();
        if (cmd?.CmdType != (int)EnumTaskType.Warehousing)
        {
            taskCmd = _TaskCmd.CreateTaskCmd(new()
            {
                TaskId = task.Id,
                TaskNo = task.TaskNo,
                TaskType = type,
                EquipId = startEquip,
                StartLoc = startLoc,
                CurrentLoc = startLoc,
                TargetLoc = targetLoc,
                CmdStatus = status,
                CmdType = type,
            });
        }

        // 修改任务
        if (taskCmd is not null)
        {
            task.TargetLoc = targetLoc;
            db.WcsTasks.Where(t => t.Id == taskId).Update(new POWcsTask
            {
                TaskType = type,
                CurrentEquip = startEquip,
                CurrentLoc = startLoc,
                TargetEquip = targetEquip,
                TargetLoc = targetLoc,
                TaskStatus = status,
                TaskGroup = groupNo,
                TaskGroupIndex = groupIndex,
                RemarkMemo = $"{task.TaskGroup} | {task.RemarkMemo}",
            });
            db.SaveChanges();
        }

        return new TaskInfoBean
        {
            POWcsTask = task,
            POWcsTaskCmd = taskCmd
        };
    }


    public TaskInfoBean CreateTaskAndCmd(TaskDTO taskDTO)
    {

        var task = CreateTask(taskDTO);

        if (task is null)
        {
            return null;
        }
        var taskCmd = _TaskCmd.CreateTaskCmd(new()
        {
            TaskId = task.Id,
            TaskNo = task.TaskNo,
            TaskType = task.TaskType,
            EquipId = task.StartEquip,
            StartLoc = task.StartLoc,
            CurrentLoc = task.CurrentLoc,
            TargetLoc = task.TargetLoc,
            CmdStatus = (int)EnumTaskCmdStatus.Executable,
            CmdType = task.TaskType,
        });
        return new TaskInfoBean
        {
            POWcsTask = task,
            POWcsTaskCmd = taskCmd
        };
    }

    public POWcsTask CreateTaskGroup(TaskDTO taskDTO)
    {
        var startLoc = taskDTO.StartLoc;
        var targetLoc = taskDTO.TargetLoc;
        var type = taskDTO.Type;
        var startEquip = taskDTO.StartEquip;
        var targetEquip = taskDTO.TargetEquip;
        var group = taskDTO.GroupNo;
        var skuId = taskDTO.SkuId;
        var scanCount = taskDTO.ScanCount;
        var remark = taskDTO.Remark;
        var directDelivery = taskDTO.DirectDelivery;
        var directSummaryId = taskDTO.DirectSummaryId;
        var directMasterId = taskDTO.DirectMasterId;
        var isSecNoread = taskDTO.IsSecNoread ?? 0;
        var startTaskType = taskDTO.StartTaskType ?? 0;
        var pairStatus = taskDTO.PairStatus ?? 0;

        if (startLoc == 0 || targetLoc == 0)
        {
            return null;
        }
        if (!Enum.IsDefined(typeof(EnumTaskType), type))
        {
            return null;
        }
        var currentLoc = startLoc;
        if (startEquip == 0)
        {
            startEquip = _WcsEquipLoc.GetEquipIdByLocId(startLoc); // 获取开始设备
        }
        else
        {
            currentLoc = _WcsEquipLoc.GetLocIdByEquipId(startEquip.GetValueOrDefault());
        }
        if (targetEquip == 0)
        {
            targetEquip = _WcsEquipLoc.GetEquipIdByLocId(targetLoc); // 获取目标设备
        }

        // 类型转换
        var isAbnormal = false;
        if (type == (int)EnumTaskType.Abnormal)
        {
            type = (int)EnumTaskType.Warehousing;
            isAbnormal = true;
        }
        WriteLog($"创建任务taskno111", true);
        var taskNo = K8.LSF.Client.CodeValue(new DateTime(), "TaskNo").ToInt(0);//new Random(9999).Next();
        var groupIndex = 2;
        if (group == 0)
        {
            group = taskNo;
            groupIndex = 1;
        }
        WriteLog($"创建任务taskno222,{taskNo}", true);
        POWcsTask pOWcsTask = new();
        try
        {
            pOWcsTask = new()
            {
                Id = XID.Nextval,
                TaskNo = taskNo,
                SkuId = skuId,
                StartEquip = startEquip,
                StartLoc = startLoc,
                TaskGroup = group,
                TaskGroupIndex = groupIndex,
                CurrentEquip = startEquip,
                CurrentLoc = currentLoc,
                TargetEquip = targetEquip,
                TargetLoc = targetLoc,
                TaskStatus = (int?)EnumTaskStatus.Executable,
                TaskType = type,
                IsAbnormal = isAbnormal,
                ScansCount = scanCount,
                IsSecNoread = isSecNoread,

                SummaryId = directSummaryId,
                MasterId = directMasterId,
                DirectDelivery = directDelivery,
                RemarkMemo = remark,
                TooltipMemo = remark,
                StartTaskType = startTaskType,
                PairStatus = pairStatus,
            };

            var db = Db.Default;
            db.WcsTasks.Insert(pOWcsTask);
            return pOWcsTask;
        }
        catch (Exception ex)
        {
            WriteLog($"创建任务333333异常,{ex.ToString()}", true);


        }
        return pOWcsTask;
    }

    public TaskInfoBean CreateTaskAndCmdGroup(TaskDTO taskDTO)
    {

        var task = CreateTaskGroup(taskDTO);
        if (task is null)
        {
            return null;
        }
        var targetCmdLoc = taskDTO.TargetCmdLoc;
        var cmdType = taskDTO.CmdType;
        var taskCmd = _TaskCmd.CreateTaskCmd(new()
        {
            TaskId = task.Id,
            TaskNo = task.TaskNo,
            TaskType = task.TaskType,
            EquipId = task.StartEquip,
            StartLoc = task.StartLoc,
            CurrentLoc = task.CurrentLoc,
            TargetLoc = targetCmdLoc,
            CmdStatus = (int)EnumTaskCmdStatus.Executable,
            CmdType = cmdType == 0 ? task.TaskType : cmdType,
        });
        return new TaskInfoBean
        {
            POWcsTask = task,
            POWcsTaskCmd = taskCmd
        };
    }

    private POWcsTask CreateOutOrderTask(TaskBean taskBean, int type, int status)
    {
        var startLoc = taskBean.StartLoc;
        var targetLoc = taskBean.TaskTargetLoc;
        var startEquip = taskBean.Fork.Fork;
        var targetEquip = _WcsEquipLoc.GetEquipIdByLocId(taskBean.TaskTargetLoc ?? 0);
        var summaryId = taskBean.SummaryId;
        var masterId = taskBean.MasterId;
        var groupNo = taskBean.GroupNo;
        var groupIndex = taskBean.Index;
        var outputLoc = taskBean.OutputLoc;
        var startCrnId = taskBean.Fork.CrnId;
        var startTaskType = taskBean.StartTaskType ?? 0;
        if (startLoc == 0 || targetLoc == 0)
        {
            return null;
        }

        if (!Enum.IsDefined(typeof(EnumTaskType), type))
        {
            return null;
        }

        // 堆垛机货叉位置
        var currentLoc = _WcsEquipLoc.GetLocIdByEquipId(startEquip.GetValueOrDefault());
        // 当前位置skuId
        var wcsLocSku = _WcsLocSku.GetWcsLocSkuNoTaskByLocId(startLoc.GetValueOrDefault());

        if (wcsLocSku is null)
        {
            ////WriteLog($"出库 位置:{startLoc},获取当前位置SKU ID:{wcsLocSku?.SkuId}.");
            return null;
        }


        int finalCuringTime = 0;
        var mesCuringRequestMaterial = _MesCuringRequestMaterial.GetCuringRequestMaterialByLocId(targetLoc.GetValueOrDefault());
        string reamrk = string.Empty;
        if (mesCuringRequestMaterial is not null)
        {
            //输送任务数
            var transTaskCount = GetTaskByType((int)EnumTaskType.Transportation).Where(t => t.TargetLoc == targetLoc).Count();
            //EMS任务数
            var EMSTaskCount = GetTaskByType((int)EnumTaskType.EMS).Where(t => t.TargetLoc == targetLoc).Count();

            var maxCacheCount = mesCuringRequestMaterial.MaxCacheCount;
            //缓存数量
            var realCacheCount = mesCuringRequestMaterial.RealCacheCount ?? 0;
            //叉上还有一个 mes中也算到了缓存数 需要减掉
            realCacheCount = realCacheCount - 1;
            //出库输送中(类型为出库任务、EMS任务)胎胚任务数
            var transAndEmsCount = transTaskCount + EMSTaskCount;
            //硫化时长(这条胎硫化的剩余时间)
            var curingTime = mesCuringRequestMaterial.CuringTime ?? 0;
            //当前时间
            var currentTime = DateTime.Now;
            //开始硫化时间
            var currentCuringTime = mesCuringRequestMaterial.CurrentCuringTime ?? currentTime;
            //一条胎硫化的总时长
            var realCuringTime = (int)(currentTime - (DateTime)currentCuringTime).TotalSeconds + curingTime;
            //输送时长
            var transTime = _WcsEquipWarehouseDistance.GetCrnToCuringTransTime(startCrnId.GetValueOrDefault(), targetLoc.GetValueOrDefault());

            //finalCuringTime = (realCacheCount + transAndEmsCount) * curingTime + (curingTime - (int)(currentTime - (DateTime)currentCuringTime).TotalSeconds) - transTime;
            //如果剩余硫化时间为0 则给个默认时间 10分钟
            if (curingTime == 0)
            {
                realCuringTime = 600;
            }
            var curingTotalTime = mesCuringRequestMaterial.CuringTotalTime;
            //如果有硫化时间 则按硫化时间计算
            if (curingTotalTime != 0)
            {
                realCuringTime = curingTotalTime ?? 0;
            }



            ////最终硫化时间  (任务数+缓存数)*一条胎硫化的总时长 + 当前硫化轮胎剩余时长- 输送时长
            finalCuringTime = (realCacheCount + transAndEmsCount) * realCuringTime + curingTime - transTime;

            reamrk = $"计算硫化时长参数（输送任务数:{transTaskCount}-EMS任务数:{EMSTaskCount}-缓存数量:{realCacheCount}-硫化剩余时间:{curingTime}-硫化开始时间:{currentCuringTime}-输送时长:{transTime}）";
        }

        POWcsTask pOWcsTask = new()
        {
            Id = XID.Nextval,
            TaskNo = K8.LSF.Client.CodeValue(new DateTime(), "TaskNo").ToInt(0),
            SkuId = wcsLocSku?.SkuId,
            StartEquip = startEquip,
            StartLoc = startLoc,
            CurrentEquip = startEquip,
            CurrentLoc = currentLoc,
            TargetEquip = targetEquip,
            TargetLoc = targetLoc,
            SummaryId = summaryId,
            MasterId = masterId,
            TaskStatus = status,
            TaskType = type,
            TaskGroup = groupNo,
            TaskGroupIndex = groupIndex,
            HouseOutputLoc = outputLoc,
            CuringTime = finalCuringTime,
            TooltipMemo = reamrk,
            StartTaskType = startTaskType,
        };

        var db = Db.Default;
        var result = db.WcsTasks.Insert(pOWcsTask);
        if (result > 0)
        {
            return pOWcsTask;
        }
        return null;
    }

    public TaskInfoBean CreateOutOrderTaskAndCmd(TaskBean taskBean, int type, int status)
    {
        taskBean.OutputLoc = taskBean.CmdTargetLoc;
        var task = CreateOutOrderTask(taskBean, type, status);
        if (task is null)
        {
            return null;
        }


        var targetLoc = taskBean.CmdTargetLoc;
        var taskCmd = _TaskCmd.CreateTaskCmd(new()
        {
            TaskId = task.Id,
            TaskNo = task.TaskNo,
            TaskType = task.TaskType,
            EquipId = task.StartEquip,
            StartLoc = task.StartLoc,
            CurrentLoc = task.CurrentLoc,
            TargetLoc = targetLoc,
            CmdStatus = status,
            CmdType = task.TaskType,
        });

        return new TaskInfoBean
        {
            POWcsTask = task,
            POWcsTaskCmd = taskCmd
        };
    }

    private TaskInfoBean CreateAbnormalTask(long startLoc, long skuId, string remark, int taskNo, long equipId = 0)
    {
        // 获取异常
        var abnormal = _WcsNetAbnormal.GetWcsNetAbnormalByStartLoc(startLoc);
        if (abnormal is null)
        {
            return null;
        }
        var id = abnormal.Id.GetValueOrDefault();
        var targetLoc = abnormal.TargetLoc.GetValueOrDefault();
        var targetLoc1 = abnormal.TargetLoc1.GetValueOrDefault();
        var nowLoc = abnormal.NowLoc.GetValueOrDefault();
        var target = targetLoc;
        if (targetLoc1 != 0)
        {
            target = nowLoc == targetLoc ? targetLoc1 : targetLoc;
        }

        var result = CreateTaskAndCmd(new()
        {
            StartLoc = startLoc,
            TargetLoc = target,
            Type = (int)EnumTaskType.Abnormal,
            SkuId = skuId,
            StartEquip = equipId,
            Remark = $"{remark} | [{startLoc}] | [{skuId}]",
            TaskNo = taskNo,
        });

        _WcsNetAbnormal.UpdateAbnormalNowLoc(id, target);

        return result;
    }


    private TaskInfoBean CreateAbnormalTaskNo(long startLoc, long skuId, string remark, int lineTaskNo = 0)
    {
        // 获取异常
        var abnormal = _WcsNetAbnormal.GetWcsNetAbnormalByStartLoc(startLoc);
        if (abnormal is null)
        {
            return null;
        }
        var id = abnormal.Id.GetValueOrDefault();
        var targetLoc = abnormal.TargetLoc.GetValueOrDefault();
        var targetLoc1 = abnormal.TargetLoc1.GetValueOrDefault();
        var nowLoc = abnormal.NowLoc.GetValueOrDefault();
        var target = targetLoc;
        if (targetLoc1 != 0)
        {
            target = nowLoc == targetLoc ? targetLoc1 : targetLoc;
        }

        var result = CreateTaskAndCmd(new()
        {
            StartLoc = startLoc,
            TargetLoc = target,
            Type = (int)EnumTaskType.Abnormal,
            SkuId = skuId,
            TaskNo = lineTaskNo,
            //Remark = $"{remark} | [{startLoc}] | [{skuId}]",
            Remark = $"{remark}",

        });

        _WcsNetAbnormal.UpdateAbnormalNowLoc(id, target);

        return result;
    }
    /// <summary>
    /// 创建环形异常口
    /// </summary>
    /// <param name="startLoc"></param>
    /// <param name="skuId"></param>
    /// <param name="remark"></param>
    /// <param name="lineTaskNo"></param>
    /// <returns></returns>
    private TaskInfoBean CreateCircularAbnormalTaskNo(long startLoc, long skuId, string remark, int lineTaskNo = 0)
    {
        // 获取异常
        var abnormal = _WcsNetAbnormal.GetWcsNetAbnormalByStartLoc(startLoc);
        if (abnormal is null)
        {
            return null;
        }
        var id = abnormal.Id.GetValueOrDefault();
        var targetLoc = abnormal.TargetLoc.GetValueOrDefault();
        var targetLoc1 = abnormal.TargetLoc1.GetValueOrDefault();
        var nowLoc = abnormal.NowLoc.GetValueOrDefault();
        var target = targetLoc;
        if (targetLoc1 != 0)
        {
           // target = nowLoc == targetLoc ? targetLoc1 : targetLoc;
            target = targetLoc1;//替换为环形线异常口
        }

        var result = CreateTaskAndCmd(new()
        {
            StartLoc = startLoc,
            TargetLoc = target,
            Type = (int)EnumTaskType.Abnormal,
            SkuId = skuId,
            TaskNo = lineTaskNo,
            //Remark = $"{remark} | [{startLoc}] | [{skuId}]",
            Remark = $"{remark}",

        });

        _WcsNetAbnormal.UpdateAbnormalNowLoc(id, target);

        return result;
    }
    private TaskInfoBean CreateOutAbnormalTaskNo(long startLoc, long skuId, string remark, int lineTaskNo = 0)
    {
        // 获取异常
        var abnormal = _WcsNetAbnormal.GetWcsNetAbnormalByStartLoc(startLoc);
        if (abnormal is null)
        {
            return null;
        }
        var id = abnormal.Id.GetValueOrDefault();
        var targetLoc = abnormal.TargetLoc.GetValueOrDefault();
        var targetLoc1 = abnormal.TargetLoc1.GetValueOrDefault();
        var nowLoc = abnormal.NowLoc.GetValueOrDefault();
        var target = targetLoc;
        if (targetLoc1 != 0)
        {
            target = nowLoc == targetLoc ? targetLoc1 : targetLoc;
        }

        var result = CreateTaskAndCmd(new()
        {
            StartLoc = startLoc,
            TargetLoc = target,
            Type = (int)EnumTaskType.Abnormal,
            SkuId = skuId,
            TaskNo = K8.LSF.Client.CodeValue(new DateTime(), "TaskNo").ToInt(0),
            //Remark = $"{remark} | [{startLoc}] | [{skuId}]",
            Remark = $"{remark}",

        });

        _WcsNetAbnormal.UpdateAbnormalNowLoc(id, target);

        return result;
    }


    public long CreateAbnormalResultTaskId(long startLoc, long skuId, string remark, int lineTaskNo) => CreateAbnormalTaskNo(startLoc, skuId, remark, lineTaskNo)?.POWcsTask?.Id ?? 0;
    public long CreateCircularAbnormalResultTaskId(long startLoc, long skuId, string remark, int lineTaskNo) => CreateCircularAbnormalTaskNo(startLoc, skuId, remark, lineTaskNo)?.POWcsTask?.Id ?? 0;

    

    public long CreateAbnormalResultCmdId(long startLoc, long skuId, string remark, int taskNo, long equipId) => CreateAbnormalTask(startLoc, skuId, remark, taskNo, equipId)?.POWcsTaskCmd?.Id ?? 0;

    public long CreateOutAbnormalResultTaskId(long startLoc, long skuId, string remark, int lineTaskNo) => CreateOutAbnormalTaskNo(startLoc, skuId, remark, lineTaskNo)?.POWcsTask?.Id ?? 0;


    public int UpdateTaskStatusByTaskId(long locId, long taskId, int status)
    {
        var task = GetTaskByTaskId(taskId);
        if (task is null)
        {
            return 0;
        }

        var bean = new POWcsTask
        {
            TaskStatus = status,
            UpdateTime = DateTime.Now
        };

        long? finishLoc = null;
        int? finishMode = (int)EnumTaskStatus.Create;
        DateTime? finishTime = null;
        //加上了入库前验证  lsq
        if (status == (int)EnumTaskStatus.Finish)
        {
            // 完成时修改
            finishLoc = locId;
            finishMode = (int)EnumFinishMode.NormalEnd;
            finishTime = DateTime.Now;

            bean = new POWcsTask
            {
                TaskStatus = status,
                FinishLoc = finishLoc,
                FinishMode = finishMode,
                FinishTime = finishTime
            };

        }
        //任务下发时 修改入库任务的配对状态为已执行
        if (task.StartTaskType == 1 && status == (int)EnumTaskStatus.Executed)
        {
            bean.PairStatus = (int)EnumPairStatus.Excuted;
        }

        var db = Db.Default;
        return db.WcsTasks.Where(t => t.Id == taskId).Update(bean);
    }
    public int UpdateTaskStatusByTaskNo(long locId, int taskNo, int status, string remark = "")
    {
        var task = GetTaskByTaskNo(taskNo);
        if (task is null)
        {
            return 0;
        }

        var bean = new POWcsTask
        {
            TaskStatus = status,
            UpdateTime = DateTime.Now,
            RemarkMemo = $"{task.RemarkMemo} | {remark}",
        };

        long? finishLoc = null;
        int? finishMode = (int)EnumTaskStatus.Create;
        DateTime? finishTime = null;
        //加上了入库前验证  lsq
        if (status == (int)EnumTaskStatus.Finish)
        {
            // 完成时修改
            finishLoc = locId;
            finishMode = (int)EnumFinishMode.NormalEnd;
            finishTime = DateTime.Now;

            bean = new POWcsTask
            {
                TaskStatus = status,
                FinishLoc = finishLoc,
                FinishMode = finishMode,
                FinishTime = finishTime,

            };

        }
        var db = Db.Default;
        return db.WcsTasks.Where(t => t.TaskNo == taskNo).Update(bean);

    }

    public int UpdateTaskStatusByTaskIds(List<long> taskIds, int status)
    {
        long? finishLoc = null;
        int? finishMode = (int)EnumTaskStatus.Create;
        DateTime? finishTime = null;

        var db = Db.Default;
        return db.WcsTasks
            .Where(t => taskIds.Contains(t.Id.GetValueOrDefault()))
            .Update(new POWcsTask
            {
                TaskStatus = status,
                UpdateTime = DateTime.Now,
                FinishLoc = finishLoc,
                FinishMode = finishMode,
                FinishTime = finishTime,
                //RemarkMemo = "修改任务状态为可执行",

            });
        db.SaveChanges();
    }

    public int UpdateTaskSpray(long taskId, int isSpray)
    {

        var db = Db.Default;
        db.WcsTasks.Where(t => t.Id == taskId).Update(new POWcsTask
        {
            IsSpray = isSpray,
        });
        return db.SaveChanges();
    }

    // Func<int,int>
    public int UpdateTaskOrder(long taskId, long maseterId, long summaryId)
    {
        var db = Db.Default;
        db.WcsTasks.Where(t => t.Id == taskId).Update(new POWcsTask
        {
            MasterId = maseterId,
            SummaryId = summaryId,
        });
        return db.SaveChanges();
    }
    public int UpdateTaskAndCmdStatus(long locId, long taskId, int status) => status switch
    {
        (int)EnumTaskStatus.Executable => UpdateTaskStatusByTaskId(locId, taskId, (int)EnumTaskStatus.Executable) & _TaskCmd.UpdateTaskCmdStatus(locId, taskId, (int)EnumTaskCmdStatus.Executable),
        (int)EnumTaskStatus.Executed => UpdateTaskStatusByTaskId(locId, taskId, (int)EnumTaskStatus.Executed) & _TaskCmd.UpdateTaskCmdStatus(locId, taskId, (int)EnumTaskCmdStatus.Executed),
        (int)EnumTaskStatus.Finish => UpdateTaskStatusByTaskId(locId, taskId, (int)EnumTaskStatus.Finish) & _TaskCmd.UpdateTaskCmdStatus(locId, taskId, (int)EnumTaskCmdStatus.Finish),
        _ => 0,
    };

    // Func<int,int>
    public int UpdateTaskAndCmdStatusByTaskIds(List<long> taskIds, int status) => status switch
    {
        (int)EnumTaskStatus.Executable => UpdateTaskStatusByTaskIds(taskIds, (int)EnumTaskStatus.Executable) + _TaskCmd.UpdateTaskCmdStatusByTaskIds(taskIds, (int)EnumTaskCmdStatus.Executable),
        _ => 0,
    };

    public int BakTask(long taskId)
    {
        var task = GetTaskByTaskId(taskId);
        if (task is null)
        {
            return 0;
        }
        var db = Db.Default;

        var result = 0;
        try { result = db.BakWcsTasks.CopyFrom(task); } catch (Exception ex) { WriteLog($"备份任务异常111{ex.ToString()}", true); };
        return result;
    }
    public int BakAndDeleteTask(long taskId)
    {
        var bak = BakTask(taskId);
        WriteLog($"备份任务完成{bak}", true);
        var del = DeleteTask(taskId);
        WriteLog($"删除任务完成{del}", true);
        return del & bak;
    }

    public int UpdateTaskAbnormal(long taskId, long abnormalId, string reamrk)
    {
        var db = Db.Default;
        var result = db.WcsTasks
            .Where(t => t.Id == taskId).Update(new POWcsTask
            {
                AbnormalId = abnormalId,
                RemarkMemo = reamrk,
            });

        return db.SaveChanges();
    }

    public int BakAndDeleteTaskAndCmd(long taskId, string remarks = "",
        [CallerMemberNameAttribute] string MemberName = "",
        [CallerFilePathAttribute] string filePath = "",
        [CallerLineNumberAttribute] int callNumber = 0)
    {

        var tasks = GetTaskByTaskId(taskId);
        //异常任务不显示删除路径
        if (tasks is not null && tasks.Id is not null && tasks.Id > 0 && tasks.TaskType != 9)
        {
            try
            {
                var path = filePath.Split("\\");
                UpdateTaskRemark(taskId,
                    $"{tasks?.RemarkMemo} | {remarks} | 调用者路径{path[path.Length - 2] + "\\" + path[path.Length - 1]} -- 调用者方法名：{MemberName} -- 调用行数：{callNumber}");
            }
            catch (Exception ex)
            {
                WriteLog($"修改备注异常,{ex.ToString()}", true);
            }
        }

        var task = BakAndDeleteTask(taskId);
        var cmd = 0;
        try
        {
            cmd = _TaskCmd.BakAndDeleteCmd(taskId);
        }
        catch (Exception ex)
        {
            Thread.Sleep(1000);
            WriteLog($"{taskId}---指令删除失败:{ex.ToString()} 重新删除一遍");
            cmd = _TaskCmd.BakAndDeleteCmd(taskId);
        }
        //finally
        //{
        //    if (cmd == 0)
        //    {
        //        Thread.Sleep(1000);
        //        //WriteLog($"指令删除失败 再重新删除一遍");
        //        cmd = _TaskCmd.BakAndDeleteCmd(taskId);
        //    }
        //}

        return task & cmd;
    }
    public List<POWcsTask> GetTaskByEmsId(long emsId, long emsId2)
    {
        var db = Db.Default;
        var result = db.WcsTasks
            .Where(t => t.CurrentEquip == emsId || t.CurrentEquip == emsId2)
            .ToList();
        return result;
    }
    public int BakAndDeleteCreateTaskAndCmd(long summaryId)
    {
        var taskS = GetTaskBySummaryId(summaryId);
        if (taskS is null || (taskS is not null && taskS.TaskStatus != (int)EnumTaskStatus.Create))
        {
            return 0;
        }
        var taskId = taskS.Id.GetValueOrDefault();
        var task = BakAndDeleteTask(taskId);
        var cmd = _TaskCmd.BakAndDeleteCmd(taskId);

        return task & cmd;
    }
    public int DeleteTask(long taskId)
    {
        var result = 0;
        try
        {
            var db = Db.Default;
            result = db.WcsTasks
               .Where(t => t.Id == taskId).Delete();
        }
        catch (Exception ex)
        {
            WriteLog($"删除任务异常{ex.ToString()}", true);
        }

        return result;
    }

    private POWcsTask GetTaskByEquipId(long equipId)
    {
        var db = Db.Default;
        var result = db.WcsTasks
            .Where(t => t.StartEquip == equipId)
            .FirstOrDefault();
        return result;
    }
    public int UpdateTaskTargetLoc(long taskId, long targetLoc, long masterId, long summaryId)
    {
        var task = GetTaskByTaskId(taskId);
        if (task is null)
        {
            return 0;
        }

        var db = Db.Default;
        db.WcsTasks.Where(t => t.Id == taskId).Update(new POWcsTask
        {
            TargetLoc = targetLoc,
            MasterId = masterId,
            SummaryId = summaryId,
            UpdateTime = DateTime.Now
        });
        return db.SaveChanges();
    }
    public bool IsTaskByEquipId(long equipId) => GetTaskByEquipId(equipId) is not null;

    public List<TaskMaterial> GetTaskMaterial(List<long?> taskIds)
    {
        var db = Db.Default;
        var result = db.WcsTasks.Join(db.ProdSkus, f => f.SkuId, s => s.Id, (f, s) => new TaskMaterial
        {
            TaskId = f.Id.GetValueOrDefault(),
            EquipId = f.TargetEquip.GetValueOrDefault(),
            SkuId = f.SkuId.GetValueOrDefault(),
            TaskNo = f.TaskNo.GetValueOrDefault(),
            MaterialId = s.MaterialId.GetValueOrDefault(),
            GroupId = f.TaskGroup.GetValueOrDefault(),
        }).Where(t => taskIds.Contains(t.TaskId)).ToList();
        return result;
    }

    public List<TaskGroupCrnMaterialCount> GetTaskCrnGroupMaterial(List<PORcsEquipCrn> rcsCrns, List<POWcsAsrsCrnInput> wcsAsrsCrnInputs)
    {
        var db = Db.Default;
        List<TaskGroupCrnMaterialCount> taskGroupCrnMaterialCounts = new();
        var result = db.WcsTasks.Join(db.ProdSkus, f => f.SkuId, s => s.Id, (f, s) => new
        {
            TaskId = f.Id.GetValueOrDefault(),
            TargetLoc = f.TargetLoc.GetValueOrDefault(),
            SkuId = f.SkuId.GetValueOrDefault(),
            TaskNo = f.TaskNo.GetValueOrDefault(),
            MaterialId = s.MaterialId.GetValueOrDefault(),
        }).ToList();

        //var wcsAsrsCrnInputs = _WcsAsrsCrnInput.GetWcsAsrsCrnInputs();
        //var rcsCrns = _RcsEquipCrn.GetRcsEquipCrn();

        foreach (var item in result)
        {
            var crnInput = wcsAsrsCrnInputs.Where(t => t.InputLoc1 == item.TargetLoc || t.InputLoc2 == item.TargetLoc).FirstOrDefault();
            if (crnInput is null)
            {
                continue;
            }

            var taskGroupCrnMaterial = taskGroupCrnMaterialCounts.Where(t => t.CrnId == crnInput.CrnId).FirstOrDefault();
            if (taskGroupCrnMaterial is not null)
            {
                taskGroupCrnMaterial.Count += 1;
                continue;
            }
            var crn = rcsCrns.Where(t => t.Id == crnInput.CrnId).FirstOrDefault();
            taskGroupCrnMaterialCounts.Add(new()
            {
                WarehouseId = crn?.WarehourseId ?? 0,
                CrnId = crnInput.CrnId.GetValueOrDefault(),
                MaterialId = item.MaterialId,
                Count = 1,
            });
        }
        return taskGroupCrnMaterialCounts;
    }
    public int UpdateTaskLineTaskNo(long taskId, int lineTaskNo, long skuId, string remark)
    {
        var db = Db.Default;
        var result = db.WcsTasks.Where(t => t.Id == taskId).Update(new POWcsTask
        {
            SkuId = skuId,
            LineTaskNo = lineTaskNo,
            UpdateTime = DateTime.Now,
            RemarkMemo = remark,
        });
        return db.SaveChanges();
    }

    public int UpdateTaskReamrkByTaskId(long taskId, string remark)
    {
        var db = Db.Default;
        var result = db.WcsTasks.Where(t => t.Id == taskId).Update(new POWcsTask
        {
            RemarkMemo = remark
        });
        return db.SaveChanges();
    }

    public int UpdateTaskReamrkByTaskNo(int taskNo, string remark)
    {
        var db = Db.Default;
        var result = db.WcsTasks.Where(t => t.TaskNo == taskNo).Update(new POWcsTask
        {
            RemarkMemo = remark
        });
        return db.SaveChanges();
    }
    public int UpdateTaskDown(int taskNo, int down)
    {
        var db = Db.Default;
        var result = db.WcsTasks.Where(t => t.TaskNo == taskNo).Update(new POWcsTask
        {
            IsDownload = down
        });
        return db.SaveChanges();
    }

    public int UpdateErrorCodeByTaskNo(int taskNo, int errorCode)
    {
        var db = Db.Default;
        var result = db.WcsTasks.Where(t => t.TaskNo == taskNo).Update(new POWcsTask
        {
            ErrorCode = errorCode
        });
        return db.SaveChanges();
    }

    public int UpdateTargetCodeByTaskNo(int taskNo, int targeCode)
    {
        var db = Db.Default;
        var result = db.WcsTasks.Where(t => t.TaskNo == taskNo).Update(new POWcsTask
        {
            TargetCode = targeCode
        });
        return db.SaveChanges();
    }
    public int UpdateTargetLocByTaskId(long taskId, POWcsTask pOWcsTask)
    {
        var db = Db.Default;
        var result = db.WcsTasks.Where(t => t.Id == taskId).Update(new POWcsTask
        {
            TargetLoc = pOWcsTask.TargetLoc,
            UpdateTime = DateTime.Now,
            RemarkMemo = pOWcsTask.RemarkMemo,
        });
        return db.SaveChanges();
    }

    public int UpdateTask(long taskId, POWcsTask pOWcsTask)
    {
        var db = Db.Default;
        var result = db.WcsTasks.Where(t => t.Id == taskId).Update(new POWcsTask
        {
            TaskNo = pOWcsTask.TaskNo,
            TaskType = pOWcsTask.TaskType,
            RemarkMemo = pOWcsTask.RemarkMemo,
            LineTaskNo = pOWcsTask.LineTaskNo,
        });
        return db.SaveChanges();
    }

    public int UpdateTaskCurrentEquip(long taskId, long equipId, long locId)
    {
        var db = Db.Default;
        var result = db.WcsTasks.Where(t => t.Id == taskId).Update(new POWcsTask
        {
            CurrentEquip = equipId,
            CurrentLoc = locId
        });
        return db.SaveChanges();
    }

    public int UpdateTaskScansCount(long taskId, int count)
    {
        if (taskId == 0)
        {
            return 0;
        }

        var db = Db.Default;
        var result = db.WcsTasks.Where(t => t.Id == taskId).Update(new POWcsTask
        {
            TaskStatus = (int)EnumTaskStatus.Executable,
            ScansCount = count,
        });
        return db.SaveChanges();


    }


    //public void Main()
    //{
    //    var dbHelper = getDbHelper();
    //    finish_3_wcs_task(dbHelper);
    //}


    //private K8.CBB.DbHelper getDbHelper()
    //{

    //    var response = K8.RPC.Service.Client.Execute("KingerRobot.WanliMDC.Spi.SysDatabaseService,KingerRobot.WanliMDC.Spi", "GetDefaultDbConfig", null);
    //    var dbConfig = response.ServiceData.ServiceData.ToObject<K8.CBB.DbConfig>();
    //    var dbHelper = new K8.CBB.DbHelper(dbConfig);
    //    return dbHelper;
    //}

    //private void finish_3_wcs_task(K8.CBB.DbHelper dbHelper)
    //{
    //    dbHelper.CommandText = @"finish_3_wcs_task";
    //    dbHelper.CommandType = System.Data.CommandType.StoredProcedure;
    //    dbHelper.ClearParameters();
    //    dbHelper.ExecuteNonQuery();
    //}


    /// <summary>
    /// 删除任务
    /// </summary>
    /// <returns></returns>
    public int DeleteOrCompleteHandTask()
    {
        var result = 0;
        var db = Db.Default;
        try
        {
            var taskList = db.WcsTasks.Where(t => t.TaskWmsStatus != 0 && t.UseFlag == 1).ToList();
            //区分前段类型
            var finishTaskList = taskList.Where(t => t.TaskWmsStatus == 13).ToList();
            var deleteTaskList = taskList.Where(t => t.TaskWmsStatus == 12 ).ToList();

            //人工删除任务
            foreach (var task in deleteTaskList)
            {
                var remark = "【手工删除】";
                UpdateTaskReamrkByTaskId(task.Id ?? 0, $"{remark}{task.RemarkMemo}");
                //备份并删除任务
                switch (task.TaskType)
                {
                    case (int)EnumTaskType.Warehousing:
                        result = DeleteTaskWarehous(task, 1);
                        break;
                    case (int)EnumTaskType.Exwarehouse:
                        result = DeleteTaskExWarehous(task, 1);
                        break;
                    case (int)EnumTaskType.Abnormal:
                        result = DeleteAbnormal(task);
                        break;
                    case (int)EnumTaskType.Transportation:
                        result = DeleteTaskTransportation(task);
                        break;
                    case (int)EnumTaskType.EMS:
                    case (int)EnumTaskType.EmsEmpty:
                        result = DeleteTaskEms(task);
                        break;
                    default:
                        result = DeleteAbnormal(task);
                        break;
                }
            }
            //人工完成任务——同步MES  入库完成写入一次，出库写入一次，EMS小车写入一次
            foreach (var task in finishTaskList)
            {
                // 修改备注
                UpdateTaskReamrkByTaskId(task.Id.GetValueOrDefault(), $"{task.RemarkMemo},人工完成");
                switch (task.TaskType)
                {
                    case (int)EnumTaskType.Warehousing:
                        WarehousingTaskFinish(task);
                        break;
                    case (int)EnumTaskType.Exwarehouse:
                        ExwarehouseTaskFinish(task);
                        break;
                    case (int)EnumTaskType.EMS:
                        EMSTaskFinish(task);
                        break;
                    case (int)EnumTaskType.EmsEmpty:
                        EmsEmptyTaskFinish(task);
                        break;
                    case (int)EnumTaskType.Abnormal:
                        AbnormalTaskFinish(task);
                        break;
                    case (int)EnumTaskType.Transportation:
                        DeleteTaskTransportation(task);
                        break;
                    //case (int)EnumTaskType.Transportation:
                    //    TaskTransportationTaskFinish(task);
                    //    break;
                    default:
                       // AbnormalTaskFinish(task);
                        break;
                }

            }

            #region MyRegion
            //using (var transaction = db.Database.BeginTransaction())
            //{
            //    try
            //    {
            //        //设置 货位 与 SKU表状态
            //        db.WcsLocSkus.Where(t => t.TaskId == wcsTasks.Id).Update(new POWcsLocSku() { UseFlag=0, RemarkMemo = $"人工删除：taskNo:[{wcsTasks.Id}]" });
            //        //更新货位信息
            //        db.RcsLocations.Where(t => t.TaskId == wcsTasks.Id).Update(new PORcsLocation()
            //        {
            //            TaskOccupy=0,
            //            TaskId=null,
            //            TaskOccupyTime=null,
            //            UpdateTime=DateTime.Now,
            //            Remarks= $"人工删除任务：taskId:[{wcsTasks.Id}]",
            //        });

            //        //删除指令表
            //        var cmds = db.WcsTaskCmds.Where(t => t.TaskNo == wcsTasks.TaskNo);
            //        foreach (var cmd in cmds)
            //        {
            //            cmd.FinishMode = (int)EnumFinishMode.SystemDelete;
            //            cmd.RemarkMemo = $"人工删除任务：taskId:[{wcsTasks.Id}]";
            //            db.Update(cmd);
            //            try { db.BakWcsTaskCmds.CopyFrom(cmd); }
            //            catch (Exception ex)
            //            {// WriteLog(ex.ToString());
            //            };
            //            result += db.WcsTaskCmds.Where(r => r.Id == cmd.Id).Delete();
            //        }

            //        //删除任务表
            //        wcsTasks.TaskStatus = (int)EnumTaskStatus.Finish;
            //        wcsTasks.FinishMode = (int)EnumFinishMode.SystemDelete;
            //        wcsTasks.RemarkMemo = $"人工删除任务：taskId:[{wcsTasks.Id}]";
            //        db.Update(wcsTasks);
            //        result = db.BakWcsTasks.CopyFrom(wcsTasks);
            //        result = db.WcsTasks.Where(t => t.Id == wcsTasks.Id).Delete();

            //        db.SaveChanges();
            //        transaction.Commit();
            //        return 1;
            //    }
            //    catch (Exception ex)
            //    {
            //        transaction.Rollback();
            //        WriteLog($"批量创建任务和指令出错:{ex.Message}");
            //        return 0;
            //    }
            //} 
            #endregion
        }
        catch (Exception ex)
        {
            WriteLog($"删除任务异常{ex.ToString()}", true);
        }

        return result;
    }
    public int AbnormalTaskFinish(POWcsTask task)
    {
        var taskId = task?.Id ?? 0;
        var taskNo = task?.TaskNo ?? 0;
        var taskCmd = _TaskCmd.GetExecutedTaskCmdByTaskNo(taskNo);
        var equipId = taskCmd?.EquipId ?? 0;
        var startLoc = _WcsEquipLoc.GetLocIdByEquipId(equipId);
        // 修改货位标识
        var targetLoc = taskCmd.TargetLoc.GetValueOrDefault();
        // 获取 skuID
        if (task?.SkuId is not long skuId)
        {
            WriteLog($"人工完成异常任务{task.TaskNo},514", true);
            return 0;
        }
        WriteLog($"人工完成异常任务{task.TaskNo},517", true);
        _RcsLocation.UpdateLocationAndWcsLocWithSkuId(skuId, startLoc, 0);
        WriteLog($"人工完成异常任务{task.TaskNo},518", true);
        // 修改状态
        UpdateTaskAndCmdStatus(targetLoc, taskId, (int)EnumTaskCmdStatus.Finish);
        WriteLog($"人工完成异常任务{task.TaskNo},519", true);
        // 备份删除
        BakAndDeleteTaskAndCmd(taskId);
        return 0;
    }
    public int TaskTransportationTaskFinish(POWcsTask task)
    {
       
        return 0;
    }
    //完成空车任务
    public int EmsEmptyTaskFinish(POWcsTask task)
    {
        var taskId = task?.Id ?? 0;
        var taskNo = task?.TaskNo ?? 0;
        var taskCmd = _TaskCmd.GetExecutedTaskCmdByTaskNo(taskNo);
        WriteLog($"人工完成空车{task.TaskNo},312", true);
        //完成任务
        // 修改货位标识
        var targetLoc = taskCmd.TargetLoc.GetValueOrDefault();
        // 修改状态
        UpdateTaskAndCmdStatus(targetLoc, taskId, (int)EnumTaskCmdStatus.Finish);
        WriteLog($"人工完成空车{task.TaskNo},319", true);
        // 备份删除
        BakAndDeleteTaskAndCmd(taskId);
        return 0;
    }
    // EMS任务完成
    public int EMSTaskFinish(POWcsTask task)
    {
        WriteLog($"人工完成{task.TaskNo},211", true);
        var taskId = task?.Id ?? 0;
        var taskNo = task?.TaskNo ?? 0;
        var taskCmd = _TaskCmd.GetExecutedTaskCmdByTaskNo(taskNo);
        WriteLog($"人工完成{task.TaskNo},212", true);
        // 获取ems 位置
        var equipId = taskCmd?.EquipId ?? 0;
        var startLoc = _WcsEquipLoc.GetLocIdByEquipId(equipId);
        WriteLog($"人工完成{task.TaskNo},213", true);
        // 获取 skuID
        if (task?.SkuId is not long skuId)
        {
            WriteLog($"人工完成{task.TaskNo},214", true);
            return 0;
        }
        WriteLog($"人工完成{task.TaskNo},215", true);
        var summary = _WmsOutOrderSummary.GetOutOrderSummaryById(task.SummaryId ?? 0);
        // 出库单完成-备份
        _WmsOutOrderMaster.OutOrderFinish(task);
        WriteLog($"人工完成{task.TaskNo},216", true);
        // 修改货位标识
        var targetLoc = taskCmd.TargetLoc.GetValueOrDefault();
        WriteLog($"人工完成{task.TaskNo},217", true);
        _RcsLocation.UpdateLocationAndWcsLocWithSkuId(skuId, startLoc, targetLoc);
        WriteLog($"人工完成{task.TaskNo},218", true);
        // 修改状态
        UpdateTaskAndCmdStatus(targetLoc, taskId, (int)EnumTaskCmdStatus.Finish);
        WriteLog($"人工完成{task.TaskNo},219", true);
        // 备份删除
        BakAndDeleteTaskAndCmd(taskId);
        WriteLog($"人工完成{task.TaskNo},220", true);
        // 同步MES
        SyncEMSMes(skuId, task.SummaryId ?? 0, task?.TaskType ?? 0);
        return 1;
    }
    /// <summary>
    /// EMS小车完成
    /// </summary>
    /// <param name="skuId"></param>
    /// <param name="summaryId"></param>
    /// <param name="taskType"></param>
    private void SyncEMSMes(long skuId, long summaryId, int targetLoc)
    {
        WriteLog($"ems人工完成开始推送信息skuId-{skuId},summary{summaryId},targetloc{targetLoc}", true);
        var tireBarcode = _ProdProduct.GetCodeBySkuId(skuId);
        //var summary = _WmsOutOrderSummary.GetBakOutOrderSummaryById(summaryId);
        var summary = _WmsOutOrderSummary.GetOutOrderSummaryById(summaryId);
        var material = _ProdMaterial.GetMaterialById(summary?.MaterialId ?? 0);
        var productionId = _ProdProduct.GetFilmPrductInfoBySkuId(skuId);
        var curingRL = _RcsEquipCuring.GetCuringRLByCuringLocId(targetLoc);
        var equipNo = curingRL?.CuringCode;
        var model = curingRL?.Mode;

        var mesService = K8.RSF.Client.Create<IMesService>();
        EndParam param = new EndParam()
        {
            TcmNo = equipNo,
            TcmDir = model,
            TcmSpec = material?.MaterialCode,
            TcmSpecDesc = material?.MaterialCode,
            TirCode = tireBarcode,
            Angle = 0,
            TbmPs = summary.TbmPs ?? "",
            CompFlag = "E",
            //TbmSpec=mesproduct?.TbmSpec
        };
        mesService.AddOutEnd(param);
    }
    // 出库任务完成 [完成删除任务、指令、绑定目标位]
    public int ExwarehouseTaskFinish(POWcsTask task)
    {
        var taskId = task?.Id ?? 0;
        var taskNo = task?.TaskNo ?? 0;
        var taskCmd = _TaskCmd.GetExecutedTaskCmdByTaskNo(taskNo);
        // 获取 skuID
        if (task?.SkuId is not long skuId)
        {
            WriteLog($"人工出库完成{task.TaskNo},414", true);
            return 0;
        }
        // 修改状态
        UpdateTaskAndCmdStatus(taskCmd.TargetLoc.GetValueOrDefault(), taskId, (int)EnumTaskStatus.Finish);
        // 备份删除
        BakAndDeleteTaskAndCmd(taskId);
        // 修改货位标识
        _RcsLocation.UpdateLocationAndWcsLocWithSkuId(task.SkuId, task.CurrentLoc, task.TargetLoc, true);
        // 同步MES
        SyncEMSMes(skuId, task.SummaryId ?? 0, task?.TaskType ?? 0);

        return 1;
    }
    // 入库任务完成 [完成删除任务、指令、绑定目标位]
    public int WarehousingTaskFinish(POWcsTask task)
    {
        var taskId = task?.Id ?? 0;
        // 修改状态
        UpdateTaskAndCmdStatus(task.TargetLoc.GetValueOrDefault(), taskId, (int)EnumTaskStatus.Finish);
        // 备份删除
        BakAndDeleteTaskAndCmd(taskId);
        // 修改货位标识
        _RcsLocation.UpdateLocationAndWcsLocWithSkuId(task.SkuId, 0, task.TargetLoc, true);
        //tuisong Mes
        //同步MES
        SyncInMes(task.SkuId ?? 0, task.TargetLoc ?? 0);
        return 1;
    }
    /// <summary>
    /// 同步MES
    /// </summary>
    /// <param name="skuId"></param>
    /// <param name="targetLoc"></param>
    private void SyncInMes(long skuId, long targetLoc)
    {

        var mesService = K8.RSF.Client.Create<IMesService>();

        var location = _RcsLocation.GetLocationById(targetLoc);
        var tireBarcode = _ProdProduct.GetCodeBySkuId(skuId);
        mesService.AddInEndByBcdNos(tireBarcode, location?.LocCode ?? "");
    }
    // 入库任务删除
    public int DeleteTaskWarehous(POWcsTask task, int IsDisable)
    {

        if (task == null) return 1;
        var taskCmd = _TaskCmd.GetTaskCmdByTaskId(task.Id.GetValueOrDefault());

        var locType = _RcsLocation.GetLocationById(task.TargetLoc.GetValueOrDefault()).LocType;
        if (locType == (int)EnumLocType.Location && IsDisable == 1)
        {
            _RcsLocation.UpdateLocUnEnable(task.TargetLoc.GetValueOrDefault(), task.TaskNo.GetValueOrDefault());
        }
        var result = BakAndDeleteTaskAndCmd(task.Id.GetValueOrDefault());
        return result;
    }

    // 出库任务删除
    public int DeleteTaskExWarehous(POWcsTask task, int IsDisable)
    {

        if (task == null) return 1;
        var result = 0;
        var taskCmd = _TaskCmd.GetTaskCmdByTaskId(task.Id.GetValueOrDefault());
        var locType = _RcsLocation.GetLocationById(task.StartLoc.GetValueOrDefault()).LocType;
        if (locType == (int)EnumLocType.Location && IsDisable == 1)
        {

            _RcsLocation.UpdateLocUnEnable(task.StartLoc.GetValueOrDefault(), task.TaskNo.GetValueOrDefault());

        }
        try
        {
            //备份并删除出库单

            var orders = _WmsOutOrderMaster.BakAndDeleteOutOrderByTask(task);

            //备份并删除任务
            result = BakAndDeleteTaskAndCmd(task.Id.GetValueOrDefault());
        }
        catch (Exception ex)
        {
            WriteLog($"手动删除出库任务异常{ex.ToString()}", true);
        }
        return result;
    }
    // 异常任务删除
    public int DeleteAbnormal(POWcsTask task)
    {
        if (task == null) return 1;
        var result = 0;
        try
        {
            result = BakAndDeleteTaskAndCmd(task.Id ?? 0);
        }
        catch (Exception ex)
        {
            WriteLog($"手动删除异常任务异常{ex.ToString()}", true);
        }
        return result;
    }
    // 线体任务删除
    public int DeleteTaskTransportation(POWcsTask task)
    {

        if (task == null) return 1;
        var result = BakAndDeleteTaskAndCmd(task.Id.GetValueOrDefault());
        return result;
    }
    // rgv 任务删除
    public int DeleteTaskEms(POWcsTask task)
    {

        if (task == null) return 1;
        var result = 0;

        //出库和EMS任务需要还原出库订单
        try
        {
            //备份并删除出库单
            var orders = _WmsOutOrderMaster.BakAndDeleteOutOrderByTask(task);

            result = BakAndDeleteTaskAndCmd(task.Id ?? 0);
            //_WcsScanner.DeleWcsScannerByTaskId(task.Id ?? 0, "任务删除时自动删除");
        }
        catch (Exception ex)
        {
            WriteLog($"手动删除ems任务异常{ex.ToString()}", true);
            return -1;
        }
        return result;
    }

    /// <summary>
    /// 手动完成任务
    /// </summary>
    /// <param name="wcsTasks"></param>
    /// <returns></returns>
    public int CompleteHandTask(POWcsTask wcsTasks)
    {
        var result = 0;

        try
        {
            var db = Db.Default;
            using (var transaction = db.Database.BeginTransaction())
            {
                try
                {
                    //设置 货位 与 SKU表状态
                    db.WcsLocSkus.Where(t => t.TaskId == wcsTasks.Id).Update(new POWcsLocSku() { UseFlag = 0, RemarkMemo = $"人工完成：taskNo:[{wcsTasks.Id}]" });
                    //更新货位信息
                    db.RcsLocations.Where(t => t.TaskId == wcsTasks.TargetLoc).Update(new PORcsLocation()
                    {
                        TaskOccupy =0,
                        TaskId = null,
                        TaskOccupyTime = null,

                        UpdateTime = DateTime.Now,
                        Remarks = $"人工完成：taskId:[{wcsTasks.Id}]",
                    });

                    //完成指令表
                    var cmds = db.WcsTaskCmds.Where(t => t.TaskNo == wcsTasks.TaskNo).Update(new POWcsTaskCmd()
                    {
                        FinishMode = (int)EnumFinishMode.ManualEnd,
                        RemarkMemo = $"人工完成任务：taskId:[{wcsTasks.Id}]"
                    });

                    //完成任务表
                    wcsTasks.TaskStatus = (int)EnumTaskStatus.Finish;
                    wcsTasks.FinishMode = (int)EnumFinishMode.ManualEnd;
                    wcsTasks.RemarkMemo = $"人工完成任务：taskId:[{wcsTasks.Id}]";
                    result = db.WcsTasks.Where(t => t.Id == wcsTasks.Id).Update(wcsTasks);
                    //出库订单
                    result = db.WmsOutOrderMasters.Where(t => t.Id== wcsTasks.MasterId).Update(new POWmsOutOrderMaster()
                    {
                        FinishMode = (int)EnumFinishMode.ManualEnd,
                        FinishTime = DateTime.Now,
                        UpdateTime= DateTime.Now,
                        RemarkMemo = $"人工完成任务：taskId:[{wcsTasks.Id}]"
                    });
                    result = db.WmsOutOrderSummarys.Where(t => t.Id == wcsTasks.MasterId).Update(new POWmsOutOrderSummary()
                    {
                        FinishMode = (int)EnumFinishMode.ManualEnd,
                        FinishTime = DateTime.Now,
                        UpdateTime = DateTime.Now,
                        RemarkMemo = $"人工完成任务：taskId:[{wcsTasks.Id}]"
                    });
                    db.SaveChanges();
                    transaction.Commit();
                    return 1;
                }
                catch (Exception ex)
                {
                    transaction.Rollback();
                    WriteLog($"批量创建任务和指令出错:{ex.Message}");
                    return 0;
                }
            }
        }
        catch (Exception ex)
        {
            WriteLog($"删除任务异常{ex.ToString()}", true);
        }

        return result;
    }
    void Main()
    {
        runMain();
    }

    private void runMain()
    {
        try
        {
            var redis = K8.Redis.DB.Root;
            //获取数据库连接
            var config = redis.Get<DbConfig[]>(REDIS_KEY.ROOT_DBCONFIG_ALL);
            if (config == null) { throw new Exception($"[{REDIS_KEY.ROOT_APP_ALL}]数据不存在！"); }
            var dbconfig = config.Where(t => t.DbName == "PDB").FirstOrDefault();

            var dbHelper = new DbHelper(dbconfig);
            dbHelper.CommandText = @"finish_3_wcs_task";
            dbHelper.CommandType = System.Data.CommandType.StoredProcedure;
            dbHelper.ClearParameters();
            var result = dbHelper.ExecuteNonQuery();
        }
        catch (Exception ex)
        {

        }
    }

    public List<POWcsTask> GetAllTasksByWmsStatus(int status)
    {
        var db = Db.Default;
        var result = db.WcsTasks.Where(t => t.TaskWmsStatus == status).ToList();
        return result;
    }
}
class ScadaCrnTaskBean
{
    public int? TaskNo { get; set; }
    public long? Id { get; set; }
}